2016-11-25 64 views
2

我正在嘗試遍歷大型2D矢量(2 mil條目)並獲取一些示例數據。我想出了一個好辦法,就是將我的迭代器隨機移動到一個隨機列中,爲每一行分配一個隨機增量並重復這個過程。使用自定義增量遍歷2D矢量

簡化的代碼

#include <iostream> 
#include <iterator> 
#include <vector> 
#include <ctime> 

using namespace std; 


int main() 
{ 
    srand((unsigned)time(0)); 
    float _mean = 0; 
    vector<vector<size_t>> v{ { 1,2,3 },{ 4,5,6 },{ 7,8,9 } }; 
    vector<vector<size_t> >::iterator row; 
    vector<size_t>::iterator column; 
    size_t i = 0; 
    size_t shift, inc; 
    for (row = v.begin(); row < v.end(); ++row) 
    { 
     shift = rand() % 10; 
     inc = rand() % 6; 

     for (column = row->begin()+shift; column < row->end(); column += inc) // row downshift 
     { 
      _mean += *column; 
      ++i; 
     } 
    } 
    cout << _mean/i << endl; 
    system("pause"); 

} 

向量的大小不是恆定的,因此,我真的不能使之成爲一個簡單的for循環,而無需使用迭代器。

此外,我認爲,我認爲,造成這一切的錯誤。 迭代器增量超出範圍,但我仍然不知道如何(優雅地)修復它。

對於大矢量,直到其到達行末工作的代碼。 你有什麼建議可以幫助我。

在此先感謝。

+0

如果您隨後迭代每一行,它不是緩存友好的嗎? – Rakete1111

+0

實際上,我正在對行和列進行採樣,並且它「工作」,直到迭代器到達行/列的末尾。 – nikjohn

+0

我會建議每行使用一個隨機洗牌索引向量,隨機數從該向量索引獲取行數據,當你枚舉。行。它並不特別容易緩存,但我認爲你可能會對結果更加開心,特別是對於更大的矩陣。 – WhozCraig

回答

1

有兩個問題:

  • 你不能假設結束迭代可以小於另一個迭代器進行比較。這隻適用於random iterators(幸運的是,向量就是這種情況),只有它們是有效的,即在邊界內(在代碼中不能保證)。因此,條件應該是column != row->end()
  • 如果inc>1以及您錯過了結束迭代器的確切值,那麼您可能會錯過結尾。

最簡單的替代方法是:

for (int column = shift; column < row->size(); column += inc) // row downshift 
    { 
     _mean += (*row)[column]; 
     ++i; 
    } 

PS: *注意,你可能偶爾會爲0的inc這將導致一個無限循環(見WhozCraig「的評論) 。更好地確定它:inc = (rand() % 5) + 1;

+0

@ n.m。我在編輯的同時更精確地表達了我的想法(帶有迭代器類別的額外鏈接)。 – Christophe

+2

如果操作系統運行不正常,導致'rand()%6'結果爲'0',這是完全可能的。在這種情況下,循環變得無限。 – WhozCraig

+0

@Christophe列和行只是迭代器,我認爲,你不能使用賦值操作符或方法begin()和end()。 – nikjohn