2016-11-25 65 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