2016-05-26 5 views
0

Какие изменения мне нужно сделать, если я хочу пройти через вектор, подобный этому, столбцом по столбцу вместо строки?Итератор 2D-вектор по столбцу

vector<vector<bool>> vvi(nLin, vector<bool>(nCol, false)); 

vector< vector<bool> >::iterator row; 
vector<bool>::iterator col; 

    for (row = vvi.begin(); row != vvi.end(); row++) { 
     for (col = row->begin(); col != row->end(); col++) { 
      // do stuff ... 
     } 
    } 

Благодаря

+0

Возможно, вы не можете использовать итераторы для этого (если вы не пишете свой собственный), а индексирование через индекс должен работать ('vvi [row] [col]') – Zereges

+2

Подождите 'int' или' bool'? – Barry

+0

Поверните матрицу? –

ответ

1

Если вы хотите использовать vector<vector<T>> для этого, то вы можете перемещаться только в одном заказе. Обратите внимание, что это не строка-за-строкой, а столбцом-по-столбцу, а на самом деле вектор-по-вектору. Каждый суб-вектор имеет хранилище, выделенное полностью независимо от другого вектора и может быть даже разной длины, поэтому его трудно назвать «строкой».

Если вам нужна матрично-подобная (тензорная, как правило,) память, вам следует рассмотреть возможность использования некоторой библиотеки, которая обеспечивает (например, STL), например OpenCV, или обертывание единственного смежного vector в ваш собственный класс, который делает индексирование.

struct Matrix { 
    std::vector<bool> storage; 
    int ncols; 
    Matrix(int nrows, int ncols) : storage(nrows * ncols), ncols(ncols) {} 
    bool& operator[](int row, int col) { 
     return storage[row * ncols + col]; 
    } 
}; 

Затем вы можете перемещаться с помощью простых for петель или писать свои собственные итераторы.

Если это слишком много работы, вы можете придерживаться vector<vector<bool>> но использовать operator[] вместо итераторов:

for (int col = 0; col < nCols; ++col) { 
    for (int row = 0; row < nRows; ++row) { 
     bool& el = vvi[row][col]; 
     // do stuff on el 
    } 
} 
+0

. Какова ценность 'ncols'? –

0

Не использовать итераторы:

int row = 0;   // V You could also use ncol below, if you know it wont change. 
for (int col = 0; col < vvi.at(row).size(); col++) { 
    for (row = 0; row < vvi.size(); row++) { 
     // get current value by vvi.at(row).at(col) 
    } 
} 

Это небезопасно, хотя, если вы не знаю, что каждая из ваших строк имеет одинаковый размер. Вот почему мы используем .at(, или вы можете сделать свою собственную проверку границ.

1

Поскольку вы знаете, количество колонок, Ncol, вы можете произвести итераторы таким образом:

for (size_t colNo = 0; colNo < nCol; ++colNo) { 
    for (const auto& row: vvi) { 
     auto it = row.begin() + colNo; 
     // do stuff 
    } 
} 

Если вы на самом деле не нужны итераторы:

for (size_t colNo = 0; colNo < nCol; ++colNo) { 
    for (const auto& row: vvi) { 
     bool colVal = row.at(colNo); 
     // do stuff 
    } 
} 
-1

Я ответ в письменном виде в Java и для этого требуется O (число строк):

public static void main(String[] args) { 
    List<List<Integer>> list = new ArrayList<>(); 
    list.add(Arrays.asList(1,5,8)); 
    list.add(Arrays.asList(2)); 
    list.add(Arrays.asList(3,6,9,11,13)); 
    list.add(Arrays.asList(4,7,10,12)); 

    LinkedList<Iterator<Integer>> queue = new LinkedList<>(); 
    Iterator<List<Integer>> iterator = list.iterator(); 
    while (iterator.hasNext()) { 
     queue.add(iterator.next().iterator()); 
    } 

    while (!queue.isEmpty() && queue.peekFirst().hasNext()) { 
     System.out.println(queue.peekFirst().next()); 
     Iterator<Integer> garbage = queue.removeFirst(); 
     if (garbage.hasNext()) { 
      queue.add(garbage); 
     } 
    } 
} 
Смежные вопросы