迭代一个STL容器,而不是从.begin()函数开始
iterate an STL container not from the .begin()ing and wrap around
我有一个std::向量,为了简单起见,我们说它是整数。
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 .
我想从预定义的索引开始遍历所有向量元素,而不是从它开始。我想打印
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++)
您可以:
-
开发一个迭代器类,包装vector::iterator并公开你喜欢的行为(特别是:++检查end()并将其替换为begin()并调整其他"border值")
-
从3开始填充矢量,并在100处换行,这样标准迭代将看起来像你想要的。
选择取决于vector的其他用途以及需要迭代的其他内容。
假设您已经有了一个起始迭代器。如何实现这一点取决于您是使用可索引(vector)类型还是仅使用前向迭代器,还是使用键控类型。然后你可以像这样做一个循环:
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 );
这是基本的循环
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;
}
我知道这是一个相当老的问题,但是没有人提到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 (auto it = myvector.begin(); it != myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << 'n';
return 0;
}
cpp.sh/3 rdru
输出:myvector contains: 3 4 5 6 7 8 9 1 2
注意,因为my_vector
是由std::rotate
函数修改的,如果你只想迭代向量一次,这既不是很有效也不是很有用。
然而,虽然这可能不是这个问题的最佳答案,但我希望它仍然可以为有类似问题的人提供一些价值。
使用随机访问容器的解决方案非常简单,参见下面的代码。
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
);
有无数种方法可以做到这一点,并且可能所有方法(或多或少)都是相同的,因此最终取决于个人偏好和编码风格惯例。我可能会这样做:
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";
}
- 调用'begin(int [n])'没有匹配函数
- 有没有函数可以在擦除 c++ 中获取 deque.begin() 的 int 值?
- 错误:调用'begin(long double [nPoints])'没有匹配函数;使用硬编码的 int 与整数变量初始化向量
- 使用 std::set 的 .begin() 和 .end() 函数会产生意想不到的结果
- 为什么 free 函数不能在 C 数组上运行,而 std::begin 在某些情况下可以在 C++14 中运行?
- 将模式包装为 std::begin; 返回 begin(c); 到函数中
- C++ 指针上的开始/结束 (arr) - 调用 'begin(int**&)' 没有匹配函数
- 如何使用begin()自由函数
- 成员函数 .begin() 和 std::begin()
- 非成员函数 begin()/cbegin() 及其 constexpr-ness
- 使用 C++11 的 begin() 和 end() 函数通过参数确定数组维度
- 调用 'begin(int**&)' 没有匹配函数
- 避免通用容器中 begin() 和 end() 函数的重复代码
- begin() 和 end() 函数不应该是模板类 Vector 的成员函数吗?
- 迭代一个STL容器,而不是从.begin()函数开始
- Iterator::Begin()函数错误
- 为我的向量包装器和迭代器返回'begin'和'end'函数返回什么?
- C++11 std::begin 不适用于传递给模板函数的 int[]
- 从特定位置调用Upper_bound函数,而不是使用data.begin()
- 依赖begin()函数的Const迭代器