迭代STL容器而不是.beginning并回绕

时间:2011-12-16 10:38:33

标签: c++ vector iterator std

我有一个std :: vector,为了简单起见,让我们说整数。

std::vector<int> ivec;
ivec.push_back(1);
ivec.push_back(2);
... //omitting some push back's 3 to 99
ivec.push_back(100);

迭代的标准方法是已知的

std::map<int>::iterator it;
for( it = ivec.begin(); it != ivec.end(); it++ ) 
  print();

该迭代将打印1,2,3,... 100。

我想遍历从预定义索引开始而不是从it.begin()开始的所有向量元素。 我想打印

  

3,4,5,6 ... 99,100,1,2

你能在这里分享一下你的想法吗?

可以分两步完成

for( it = ivec.begin()+index; it != ivec.end(); it++ ) and then (if index !=0)

for ( it = ivec.begin; it = it = ivec.begin() + (index-1); it++)

6 个答案:

答案 0 :(得分:7)

你可以:

  • 开发一个迭代器类,它包装了vector :: iterator并公开你喜欢的行为(特别是:++检查end()并用begin()替换它并调整其他“border values”)

  • 从3开始填充向量并在100处换行,以便标准迭代看起来像你想要的那样。

选择取决于向量的目的是什么以及需要迭代的其他内容。

答案 1 :(得分:4)

我假设你已经有了一个启动迭代器。如何获得这取决于您是使用可索引(向量)类型还是仅使用前向迭代器,还是使用键控类型。然后你可以做一个像这样的循环:

type::iterator start_iter = /* something from collection, perhaps begin()+index */
type::iterator cur_iter = start_iter;
do
{
  //do something with cur_iter

  ++cur_iter;
  if( cur_iter == collection.end() )
    cur_iter = collection.begin();
} while( cur_iter != start_iter );

这是基本循环。

答案 2 :(得分:3)

bool wrapped = false;
for (auto it = vec.begin() + index; (it != vec.begin() + index) || !wrapped; ++it)
{
    if (it == vec.end())
    {
        it = vec.begin();
        wrapped = true;
    }
    std::cout << *it;
}

答案 3 :(得分:2)

使用随机访问容器时的解决方案非常简单,请参阅下面的代码。

std::vector<int> v ({1,3,4,5,6,7,8,9,10}); /* c++11 */

...

for (int i = 2; i < (10+2); ++i)
  std::cout << v[i % 10] << " ";

使用仅具有双向/前向迭代器的容器时的方法:

  std::list<int> l ({1,3,4,5,6,7,8,9,10}); /* c++11 */

  Iter start = l.begin ();
  std::advance (start, 4);

  ...

  Iter it = start;

  do {
    std::cerr << *it << std::endl;

  } while (
    (it = ++it == l.end () ? l.begin () : it) != start
  );

答案 4 :(得分:1)

我知道这是一个非常古老的问题,但没有人提到std::rotate,我认为,在某些情况下,这可能是工作的正确工具。

来自http://www.cplusplus.com/reference/algorithm/rotate/的修改示例:

#include <iostream>     // std::cout
#include <algorithm>    // std::rotate
#include <vector>       // std::vector

int main () {
  std::vector<int> myvector;

  // set some values:
  for (int i=1; i<10; ++i) myvector.push_back(i); // 1, 2, 3, ... 9

  std::rotate(myvector.begin(),myvector.begin()+2,myvector.end());
                                                  // 3, 4, 5, 6 ... 9, 1, 2
  // print out content:
  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

输出:

myvector contains: 3 4 5 6 7 8 9 1 2

注意,由于my_vector函数修改了std::rotate,如果你只想迭代一次向量,这既不是非常有效也不是有用。

然而,虽然这可能不是这个问题的最佳答案,但我希望它仍然可以为有类似问题的人提供一些价值。

答案 5 :(得分:0)

有无数的方法可以做到这一点,而且可能都是(或多或少)等价的,所以最终它取决于个人偏好和编码风格约定。我可能会这样做:

std::cout << v[idx] << "\n";
for( auto it = v.begin() + idx + 1; it != v.begin()+idx; ++it )
{
    if( it == v.end() ) it = v.begin();
    std::cout << *it << "\n";
}