Cómo crear iterador/es para el vector 2d (un vector de vectores)?iterador para el vector 2d
Respuesta
Aunque su pregunta es no muy clara, voy a asumir que quiere decir un vector 2D en el sentido de un vector de vectores:
vector< vector<int> > vvi;
Luego hay que utilizar dos iteradores para atravesarlo, la primera el iterador de las "filas", el segundo de los iteradores de las "columnas" en el que "fila":
//assuming you have a "2D" vector vvi (vector of vector of int's)
vector< vector<int> >::iterator row;
vector<int>::iterator col;
for (row = vvi.begin(); row != vvi.end(); row++) {
for (col = row->begin(); col != row->end(); col++) {
// do stuff ...
}
}
Lamento que mi pregunta no fuera tan clara, pero esto es exactamente lo que quería. Aunque obtengo un error de compilación con este código: no se puede convertir de 'std :: _ Vector_iterator <_Ty,_Alloc>' a 'int' en (fila = vvi.begin(); fila! = Vvi.end(); fila ++) { – miroslavec
siempre use operadores de pre incremento. Con los vectores es probable que no importe cuando se usa un vector, pero es un mal hábito entrar. La vida sería mucho más clara si hubiera sido ++ C en lugar de C++. –
Si solo hay 2 elementos en las columnas. Cómo acceder a ellos una vez que iteramos por la fila. –
Suponiendo que se refiera a un iterador STL, y un contenedor personalizado que implemente una matriz 2D genérica de objetos, esto es imposible. Los iteradores STL solo admiten operaciones de incremento y decremento (es decir, "siguiente" y "anterior"), donde el movimiento a través de un conjunto 2D requiere cuatro de estas primitivas (por ejemplo, izquierda/derecha/arriba/abajo, etc.). Las metáforas no coinciden.
¿Qué estás tratando de hacer?
Asumiendo que significa un vector de vectores, y tiene std::vector
en mente, no hay construyeron en forma de hacerlo, como iteradores solo admite operaciones de incremento y decremento para avanzar y retroceder.
Un vector 2D es una matriz, por lo que necesitaría dos tipos de iteradores: un iterador de fila y un iterador de columna. Los iteradores de fila moverían "hacia arriba" y "hacia abajo" la matriz, mientras que los iteradores de columna se moverían "izquierda" y "derecha".
Debe implementar estas clases de iterador usted mismo, lo cual no es necesariamente algo trivial. A menos que, por supuesto, simplemente desee iterar sobre cada ranura en la matriz, en cuyo caso un bucle for for usando las variables de índice i
y j
funcionará perfectamente. Dependiendo de sus necesidades (su publicación es un poco deficiente en contenido aquí), es posible que desee utilizar boost::numeric::ublas::matrix
, que es una clase de matriz de la biblioteca de álgebra lineal Boost. Esta clase de matriz tiene iteradores de fila y columna incorporados, lo que hace que sea más fácil iterar sobre una matriz.
Exactamente lo que quise decir, matriz de vectores 2D con (ahora sé que dos) iteradores. Pensé que las preguntas eran claras :(... de todos modos soy bastante nuevo para los vectores y tengo que usarlos en este trabajo. Ahora otro problema es ese error que publiqué en el comentario anterior (el formateo es una mierda). No puedo asignar valor al primer iterador (fila) porque ese tipo no coincide – miroslavec
Puede usar range para la instrucción para iterar todos los elementos en un vector bidimensional.
vector< vector<int> > vec;
Y supongamos que ya has push_back una gran cantidad de elementos en vec;
for(auto& row:vec){
for(auto& col:row){
//do something using the element col
}
}
Otra forma de interpretar esta pregunta es que quieres un iterador 1D durante un vector<vector<>>
por ejemplo, para alimentar a for_each()
o algún otro algoritmo.
puede hacerlo de esta manera:
#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm>
// An iterator over a vector of vectors.
template<typename T>
class vv_iterator : public std::iterator<std::bidirectional_iterator_tag, T>{
public:
static vv_iterator<T> begin(std::vector<std::vector<T>>& vv) {
return vv_iterator(&vv, 0, 0);
}
static vv_iterator<T> end(std::vector<std::vector<T>>& vv) {
return vv_iterator(&vv, vv.size(), 0);
}
vv_iterator() = default;
// ++prefix operator
vv_iterator& operator++()
{
// If we haven't reached the end of this sub-vector.
if (idxInner + 1 < (*vv)[idxOuter].size())
{
// Go to the next element.
++idxInner;
}
else
{
// Otherwise skip to the next sub-vector, and keep skipping over empty
// ones until we reach a non-empty one or the end.
do
{
++idxOuter;
} while (idxOuter < (*vv).size() && (*vv)[idxOuter].empty());
// Go to the start of this vector.
idxInner = 0;
}
return *this;
}
// --prefix operator
vv_iterator& operator--()
{
// If we haven't reached the start of this sub-vector.
if (idxInner > 0)
{
// Go to the previous element.
--idxInner;
}
else
{
// Otherwise skip to the previous sub-vector, and keep skipping over empty
// ones until we reach a non-empty one.
do
{
--idxOuter;
} while ((*vv)[idxOuter].empty());
// Go to the end of this vector.
idxInner = (*vv)[idxOuter].size() - 1;
}
return *this;
}
// postfix++ operator
vv_iterator operator++(int)
{
T retval = *this;
++(*this);
return retval;
}
// postfix-- operator
vv_iterator operator--(int)
{
T retval = *this;
--(*this);
return retval;
}
bool operator==(const vv_iterator& other) const
{
return other.vv == vv && other.idxOuter == idxOuter && other.idxInner == idxInner;
}
bool operator!=(const vv_iterator &other) const
{
return !(*this == other);
}
const T& operator*() const
{
return *this;
}
T& operator*()
{
return (*vv)[idxOuter][idxInner];
}
const T& operator->() const
{
return *this;
}
T& operator->()
{
return *this;
}
private:
vv_iterator(std::vector<std::vector<T>>* _vv,
std::size_t _idxOuter,
std::size_t _idxInner)
: vv(_vv), idxOuter(_idxOuter), idxInner(_idxInner) {}
std::vector<std::vector<int>>* vv = nullptr;
std::size_t idxOuter = 0;
std::size_t idxInner = 0;
};
int main()
{
std::vector<std::vector<int>> a = {{3, 5, 2, 6}, {-1, -4, -3, -5}, {100}, {-100}};
std::reverse(vv_iterator<int>::begin(a), vv_iterator<int>::end(a));
for (const auto& v : a)
{
std::cout << "{ ";
for (auto i : v)
std::cout << i << " ";
std::cout << "}\n";
}
}
Lienzo:
{ -100 100 -5 -3 }
{ -4 -1 6 2 }
{ 5 }
{ 3 }
Nota esto no va a trabajar con std::sort()
porque eso requiere un iterador de acceso aleatorio. Podría hacer que sea un iterador de acceso aleatorio, pero tendría que escanear el vector al inicio para que pueda mapear desde el índice plano a idxOuter
y idxInner
en tiempo constante. No es totalmente trivial, pero tampoco es difícil.
Estaba buscando exactamente su interpretación de la pregunta. Estoy en lo correcto, que este es solo el iterador no const y uno necesitaría escribir una segunda clase para el 'const_iterator'? ¿Hay alguna razón específica para almacenar índices en lugar de los iteradores de vectores? Btw me llevó un tiempo entender el ejemplo, porque el resultado utiliza los iteradores" normales ", mientras que el uso del iterador 1D está un poco oculto en esta inocente línea 'reverse' – user463035818
Sí, en mi código real tengo una versión' const_iterator'. Es más o menos una copia/pega con los miembros no const eliminados (no pude encontrar una manera de evitar el copiar/pas te). Buen punto, supongo que no hay una razón para no usar vectores iteradores. Probablemente sea mejor, simplemente no pensé en eso. – Timmmm
- 1. iterador avanzado para el std :: vector std :: advance VS operator +?
- 2. std :: invalidación de iterador de vector
- 3. ¿Diferencia de rendimiento entre el iterador ++ y el iterador ++?
- 4. ¿El iterador admite + operador?
- 5. Referencia al elemento en el vector 2d (C++)
- 6. El iterador inverso no compilará
- 7. ¿Rendimiento de acceso del iterador para el mapa STL frente al vector?
- 8. iterador "end()" para insertadores posteriores?
- 9. cómo conseguir iterador a una posición particular de un vector
- 10. iterador aritmética
- 11. Conversión de un iterador de Scala en un vector
- 12. Usando C++ vector :: insert() para agregar al final del vector
- 13. Cálculo de la Cruz de un Vector 2D Producto
- 14. Encontrar el propietario de un iterador STL
- 15. ¿Cómo declaro e inicializo un vector int 2d en C++?
- 16. Arrays bidimensionales usando el vector
- 17. ¿Convertir iterador en puntero?
- 18. Filtro jinja2 personalizado para el iterador
- 19. Scala iterador con el mapa y para
- 20. Iterador genérico
- 21. ¿Cómo usar un iterador?
- 22. iterador de acoplamiento
- 23. Enumeración Java vs iterador
- 24. Convertir iterador a int
- 25. Scala, extendiendo el iterador
- 26. Wrap vector de STL y el cambio de comportamiento de su iterador
- 27. omitiendo el iterador
- 28. Obtener un iterador inverso de un iterador directo sin saber el tipo de valor
- 29. ¿Está bien usar constructores para inicializar un vector 2D como un trazo en C++?
- 30. problemas iterador C++
¿Puede describir el contexto de la pregunta un poco mejor? – UncleBens
Más específicamente: ¿cuál es la declaración de su vector 2d? ¿Qué orden quieres iterar? ¿Cómo quieres usar el iterador? –
¿Qué es "2d vector" ??? – AnT