iterator dla wektora 2d

Jak stworzyć iterator / s dla wektora 2d (wektora wektorów)?

Author: Dima, 2009-11-23

5 answers

Chociaż twoje pytanie jest NIE bardzo jasne, zakładam, że masz na myśli wektor 2D to znaczy wektor wektorów:

vector< vector<int> > vvi;

Następnie musisz użyć dwóch iteratorów, aby go przemierzyć, pierwszy iterator "rows", drugi iterator " columns "w tym"row":

//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 ...
    }
}
 36
Author: Austin Hyde,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-23 17:54:37

Można użyć polecenia range for do iteracji wszystkich elementów w dwuwymiarowym wektorze.

vector< vector<int> > vec;

I załóżmy, że masz już push_back wiele elementów w vec;

for(auto& row:vec){
   for(auto& col:row){
      //do something using the element col
   }
}
 8
Author: ShuaiYu8,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-24 09:11:54

Innym sposobem interpretacji tego pytania jest to, że chcesz iterator 1D nad vector<vector<>> na przykład, aby przesłać go do for_each() lub innego algorytmu.

Możesz to zrobić tak:

#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";
    }
}

Druki:

{ -100 100 -5 -3 }
{ -4 -1 6 2 }
{ 5 }
{ 3 }

UWAGA To nie będzie działać z std::sort(), ponieważ wymaga to losowego iteratora dostępu. Możesz zrobić z niego iterator dostępu losowego, ale musisz skanować wektor na początku, aby móc mapować z indeksu płaskiego na idxOuter i idxInner w stałym czasie. Nie do końca trywialne, ale nie też ciężko.

 3
Author: Timmmm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-23 17:54:00

Zakładając, że masz na myśli iterator STL i Niestandardowy kontener, który implementuje ogólną tablicę obiektów 2D, jest to niemożliwe. Iteratory STL obsługują tylko operacje zwiększania i zmniejszania (tj." następne "i" poprzednie"), gdzie ruch przez zestaw 2D wymaga czterech takich prymitywów (np. lewo/prawo/góra/dół, itp...). Metafory nie pasują.

Co próbujesz zrobić?

 0
Author: Andy Ross,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-23 17:47:28

Zakładając, że masz na myśli wektor wektorów i masz na myśli std::vector, nie ma na to wbudowanego sposobu, ponieważ Iteratory obsługują tylko operacje zwiększania i zmniejszania, aby poruszać się do przodu i do tyłu.

Wektor 2D jest macierzą, więc potrzebne są dwa typy iteratorów: iterator wierszy i iterator kolumn. Iteratory wierszy przesuwałyby się" w górę "i" w dół "matrycy, podczas gdy Iteratory kolumn przesuwałyby się" w lewo "i"w prawo".

Musisz zaimplementować te klasy iteratora samodzielnie, co jest niekoniecznie trywialna rzecz do zrobienia. Chyba, że po prostu chcesz iterować nad każdym slotem w macierzy, w którym to przypadku pętla double for używając zmiennych indeksowych i i j będzie działać dobrze. W zależności od twoich potrzeb (twój post jest trochę pozbawiony treści), możesz użyć boost::numeric::ublas::matrix, która jest klasą macierzy z biblioteki algebry liniowej Boost. Ta klasa macierzy ma wbudowane Iteratory wierszy i kolumn, które generalnie ułatwiają iterację nad macierzą.

 0
Author: Charles Salvia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-23 18:00:47