如何使用迭代器导航向量?(C++)

kev*_*vin 95 c++ iterator vector

目标是访问字符串向量的"第n"元素,而不是[]运算符或"at"方法.根据我的理解,迭代器可用于浏览容器,但我以前从未使用过迭代器,而我正在阅读的内容令人困惑.

如果有人能给我一些如何实现这一目标的信息,我将不胜感激.谢谢.

cod*_*ict 102

您需要使用类的beginand end方法vector,它返回迭代器,分别引用第一个和最后一个元素.

using namespace std;  

vector<string> myvector;  // a vector of stings.


// push some strings in the vector.
myvector.push_back("a");
myvector.push_back("b");
myvector.push_back("c");
myvector.push_back("d");


vector<string>::iterator it;  // declare an iterator to a vector of strings
int n = 3;  // nth element to be found.
int i = 0;  // counter.

// now start at from the beginning
// and keep iterating over the element till you find
// nth element...or reach the end of vector.
for(it = myvector.begin(); it != myvector.end(); it++,i++ )    {
    // found nth element..print and break.
    if(i == n) {
        cout<< *it << endl;  // prints d.
        break;
    }
}

// other easier ways of doing the same.
// using operator[]
cout<<myvector[n]<<endl;  // prints d.

// using the at method
cout << myvector.at(n) << endl;  // prints d.
Run Code Online (Sandbox Code Playgroud)

  • 无论你是否知道迭代器类型是随机访问,将迭代器向前移动n个空格的"最佳"方法不是编写自己的循环,而是调用`std :: advance(it,n)`.它被定义为完全按照您的意愿执行,如果迭代器被标记为随机访问,它将自动使用`it + n`,如果必须,则执行循环. (20认同)
  • 这忽略了`std :: vector`具有随机访问迭代器的事实. (4认同)

Mic*_*yan 55

通常,迭代器用于以线性方式访问容器的元素; 但是,使用"随机访问迭代器",可以以相同的方式访问任何元素operator[].

访问向量中的任意元素 vec,可以使用以下命令:

vec.begin()                  // 1st
vec.begin()+1                // 2nd
// ...
vec.begin()+(i-1)            // ith
// ...
vec.begin()+(vec.size()-1)   // last
Run Code Online (Sandbox Code Playgroud)

以下是典型访问模式(早期版本的C++)的示例:

int sum = 0;
using Iter = std::vector<int>::const_iterator;
for (Iter it = vec.begin(); it!=vec.end(); ++it) {
    sum += *it;
}
Run Code Online (Sandbox Code Playgroud)

使用迭代器的优点是可以将相同的模式应用于其他容器:

sum = 0;
for (Iter it = lst.begin(); it!=lst.end(); ++it) {
    sum += *it;
}
Run Code Online (Sandbox Code Playgroud)

因此,无论容器类型如何,创建模板代码都非常容易.迭代器的另一个优点是它不假设数据驻留在内存中; 例如,可以创建一个前向迭代器,它可以从输入流中读取数据,或者只是动态生成数据(例如范围或随机数生成器).

使用std::for_each和lambdas的另一个选项:

sum = 0;
std::for_each(vec.begin(), vec.end(), [&sum](int i) { sum += i; });
Run Code Online (Sandbox Code Playgroud)

从C++ 11开始,您可以使用auto以避免指定迭代器的非常长,复杂的类型名称,如前所述(或者甚至更复杂):

sum = 0;
for (auto it = vec.begin(); it!=vec.end(); ++it) {
    sum += *it;
}
Run Code Online (Sandbox Code Playgroud)

此外,每种变体都有一个更简单的方法:

sum = 0;
for (auto value : vec) {
    sum += value;
}
Run Code Online (Sandbox Code Playgroud)

最后,std::accumulate无论是添加整数还是浮点数,都必须要小心.


las*_*gar 46

在C++ - 11中你可以这样做:

std::vector<int> v = {0, 1, 2, 3, 4, 5};
for (auto i : v)
{
   // access by value, the type of i is int
   std::cout << i << ' ';
}
std::cout << '\n';
Run Code Online (Sandbox Code Playgroud)

请参阅此处了解各种变体:https://en.cppreference.com/w/cpp/language/range-for

  • 为什么有零赞?!&lt;3 (4认同)
  • @jperl迟到了8年.未来8年将获得足够的支持:) (3认同)

Unc*_*ens 16

Vector的迭代器是随机访问迭代器,这意味着它们的外观和感觉就像普通的指针.

您可以通过将n添加到从容器的begin()方法返回的迭代器来访问第n个元素,或者您可以使用运算符[].

std::vector<int> vec(10);
std::Vector<int>::iterator it = vec.begin();

int sixth = *(it + 5);
int third = *(2 + it);
int second = it[1];
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用适用于各种迭代器的高级功能.(您必须考虑是否真的想要使用非随机访问迭代器执行"随机访问",因为这可能是一件昂贵的事情.)

std::vector<int> vec(10);
std::vector<int>::iterator it = vec.begin();

std::advance(it, 5);
int sixth = *it;
Run Code Online (Sandbox Code Playgroud)