Подтвердить что ты не робот

Как перемещаться по вектору с помощью итераторов? (С++)

Целью является доступ к "n-му" элементу вектора строк вместо оператора [] или "at". Насколько я понимаю, итераторы могут использоваться для навигации по контейнерам, но я никогда не использовал итераторы раньше, и то, что я читаю, путается.

Если бы кто-нибудь мог дать мне некоторую информацию о том, как этого добиться, я был бы признателен. Спасибо.

4b9b3361

Ответ 1

Вам нужно использовать begin и 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.

Ответ 2

Как правило, итераторы используются для доступа к элементам контейнера линейно; однако, с "итераторами произвольного доступа", можно получить доступ к любому элементу таким же образом, как operator[].

Чтобы получить доступ к произвольным элементам в векторе vec, вы можете использовать следующее:

vec.begin()                  // 1st
vec.begin()+1                // 2nd
// ...
vec.begin()+(i-1)            // ith
// ...
vec.begin()+(vec.size()-1)   // last

Ниже приведен пример типичного шаблона доступа (более ранние версии С++):

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

Преимущество использования итератора заключается в том, что вы можете применить тот же шаблон к другим контейнерам:

sum = 0;
for (Iter it = lst.begin(); it!=lst.end(); ++it) {
    sum += *it;
}

По этой причине очень легко создать шаблон кода, который будет работать с тем же , независимо от типа контейнера. Другим преимуществом итераторов является то, что он не предполагает, что данные хранятся в памяти; например, можно создать передовой итератор, который может считывать данные из входного потока или просто генерировать данные "на лету" (например, генератор диапазона или генератора случайных чисел).

Другой вариант с использованием std::for_each и lambdas:

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

С С++ 11 вы можете использовать auto, чтобы избежать указания очень длинного и сложного имени типа итератора, как было показано ранее (или даже более сложного):

sum = 0;
for (auto it = vec.begin(); it!=vec.end(); ++it) {
    sum += *it;
}

И, кроме того, для каждого варианта есть более простой вариант:

sum = 0;
for (auto value : vec) {
    sum += value;
}

И, наконец, есть также std::accumulate, где вы должны быть осторожны, добавляете ли вы числа целых чисел или чисел с плавающей запятой.

Ответ 3

Итераторы векторов - это итераторы произвольного доступа, что означает, что они выглядят и выглядят как простые указатели.

Вы можете получить доступ к n-му элементу, добавив n к итератору, возвращаемому из метода контейнера begin(), или вы можете использовать оператор [].

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

int sixth = *(it + 5);
int third = *(2 + it);
int second = it[1];

В качестве альтернативы вы можете использовать функцию advance, которая работает со всеми типами итераторов. (Вам нужно будет подумать, действительно ли вы хотите выполнить "произвольный доступ" с итераторами неслучайного доступа, поскольку это может быть дорогостоящим делом.)

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

std::advance(it, 5);
int sixth = *it;