You are currently browsing the tag archive for the ‘array multidimensional’ tag.
Array bidimensional
La Standard Template Library (STL) se llama a veces biblioteca estándar de C++ para distinguirla de la biblioteca estándar de C. Una de las herramientas que la biblioteca STL ofrece son contenedores. Un contenedor es un objeto que contiene un número variable de otros objetos. Todos estos objetos tienen el mismo tipo. Por ejemplo, un contenedor de enteros podría tener el tipo std::vector<int>
. En lugar de int
se podría poner cualquier otro tipo.
En particular, se podría usar otro contenedor como tipo de elemento. Un objeto de tipo std::vector<std::vector> >
sería algo como un array bidimensional. Sin embargo, no sería lo mismo que un array de tipo int[x][y]
. Esta última versión crea un array rectangular, es decir una matriz. La versión de std::vector
crearía una array dinámico de arrays dinámicos, en que cada línea podría tener un número diferente de columnas – por lo cual se parece a los arrays multidimensionales del lenguaje de programación Java.
Iteradores
Desgraciadamente no hay un contenedor multidimensional en la STL. Una razón es probablemente la iteración sobre todos los elementos. Una tarea de programación común es hacer algo con cada elemento de un contenedor. Esto se hace típicamente en un bucle for
del primer al último elemento. La STL ofrece clases especiales llamados iterator
. Iteradores son objetos que se comportan como punteros y tienen, como estos, algunas de las siguientes propiedades.
- Pueden delimitar un rango de valores apuntando al primer y al último elemento. (Más correctamente detrás del último elemento.) Los iteradores se inicializan típicamente con los métodos
begin()
yend()
del contenedor. - Pueden acceder al elemento a que apuntan – típicamente con los operadores
*
y->
. - Pueden apuntar al elemento previo o siguiente – típicamente con los operadores
--
y++
de pre-fijo o post-fijo.
Estas operaciones están bien definidas para contenedores lineales, es decir contenedores en que los elementos están ordenados de una forma específica. Esto no quiere decir que estén ordenados lógicamente, por ejemplo números pequeños primero, sino que se puede diferenciar claramente un predecesor y un sucesor de cada elemento. Pero ¿cómo podemos establecer este orden en un array multidimensional? ¿Avanzar al próximo elemento es moverse una columna o una fila más allá?
Iterar sobre una colección multidimensional
Matemáticamente no hay un orden estricto en un espacio multidimensional. No obstante, para resolver nuestro problema de iteración sólo necesitamos cumplir lo siguiente: Una iteración completa pasa por todos los elementos exactamente una vez.
¿Qué quiere decir esto? Quiere decir que no importa si vamos fila por fila o columna por columna (o por cualquier otra forma) cuando un bucle de forma
for (iterator p = container.begin(); p != container.end(); ++p) { // Do something with *p or p-> }
pasaría por todos los elemento del array. (Aquí igual te interesa por qué el incremento prefijo es más rápido que postfijo.)
Hay otro problema con los arrays multidimensionales en C++. Habitualmente nos gusta escribir algo como punto[x][y]
para referirnos a un elemento en concreto del array punto
. No obstante, no hay una método operator[][]
que podríamos sobre cargar y el método operator[]
sólo permite un parámetro.
Hay varias formas para afrontar este problema.
- El método
operator[]
de un contenedor bidimensional podría exportar una referencia a un contenedor unidimensional que igualmente sobrecarga el métodooperator[]
. Es una buena solución pero restringe la libertad de como implementar el contenedor multidimensional. - El método
operator()
permite un número arbitrario de parámetros. En lugar depunto[x][y]
escribiríamospunto(x, y)
. Este sistema es una buena solución para contenedores de un número fijo de dimensiones. - Finalmente podríamos sobrecarga el método
operator[]
usando un índice multidimensional. En lugar depunto[x][y]
opunto(x, y)
escribiríamos algo comopunto[array_index(x, y)]
. No es una solución demasiado práctica pero la única aceptable para contenedores con un número de dimensiones variable. Aunque el índice multidimensional sería otra clase que deberíamos crear para este propósito, es probable que ya lo hayamos hecho a la hora de crear las clases de los iteradores para el array multidimensional.
Conclusión
Hemos repasado unos puntos a tener en cuenta a la hora de crear contenedores multidimensionales al estilo con la STL. Como puede llegar a ser laborioso conviene buscarse implementaciones ya hechas como el componente MultiArray de la biblioteca Boost.