Итераторы
Итератор предоставляет обобщенный способ перебора элементов любого контейнера – как последовательного, так и ассоциативного. Пусть iter является итератором для какого-либо контейнера. Тогда
++iter;перемещает итератор так, что он указывает на следующий элемент контейнера, а
*iter;разыменовывает итератор, возвращая элемент, на который он указывает.
Итератор – это объект класса, поддерживающего абстракцию указательного типа. В шаблоне класса vector определены две функции-члена – begin() и end(), устанавливающие итератор соответственно на первый элемент вектора и на элемент, который следует за последним. Вместе эти две функции задают диапазон элементов вектора. Используя итератор, предыдущий пример можно переписать таким образом:
#include <vector>
#include<iostream>
#include<cstdlib>
#include<string>
using namespace std;
void main()
{
vector <int> vec(10);
vector<int>::iterator iter=vec.begin();
int S=0;
for(;iter<vec.end();iter++)
{
cin>>*iter;
S=S+(*iter);
}
cout<<S/10<<endl;
system("pause");
}
Все контейнеры имеют функции-члены begin() и end().
· begin() возвращает итератор, указывающий на первый элемент контейнера.
· end() возвращает итератор, указывающий на элемент, следующий за последним в контейнере.
Объявление итератора выглядит слишком сложным. Вот определение пары итераторов вектора типа string:
// vector<string> vec;
vector<string>::iterator iter = vec.begin();
vector<string>::iterator iter_end = vec.end();
Вот как можно определить новые векторы, инициализируя их элементами первого вектора:
int main() {
vector<string> svec;
//...
// инициализация svec2 всеми элементами svec
vector<string> svec2(svec.begin(), svec.end());
// инициализация svec3 первой половиной svec
vector<string>::iterator it =
svec.begin() + svec.size()/2;
vector<string> svec3 (svec.begin(), it);
//...
}
В стандартной библиотеке С++ имеется много функций, работающих с классом vector, но определенных не как функции-члены класса, а как набор обобщенных алгоритмов. Вот их неполный перечень:
|
· алгоритмы поиска: find(), find_if(), search(), binary_search(), count(), count_if();
· алгоритмы сортировки и упорядочения: sort(), partial_sort(), merge(), partition(), rotate(), reverse(), random_shuffle();
· алгоритмы удаления: unique(), remove();
численные алгоритмы: accumulate(), partial_sum(), inner_product(), adjacent_difference();
· алгоритмы генерации и изменения последовательности: generate(), fill(), transform(), copy(), for_each();
· алгоритмы сравнения: equal(), min(), max().
В число параметров этих обобщенных алгоритмов входит итераторная пара, задающая диапазон элементов вектора, к которым применяется алгоритм. Скажем, чтобы упорядочить все элементы некоторого вектора ivec, достаточно написать следующее:
sort (ivec.begin(), ivec.end());
Для использования алгоритмов в программу необходимо включить заголовочный файл
#include <algorithm>
Пример сортировки
#include <vector>
#include<iostream>
#include<cstdlib>
#include<string>
#include<algorithm>
using namespace std;
void main()
{
vector <int> vec(10);
vector<int>::iterator iterB=vec.begin();
vector<int>::iterator iterE=vec.end();
int S=0;
for(;iterB!=iterE;iterB++)
{
cin>>*iterB;
}
iterB=vec.begin();
sort(iterB,iterE);
for(;iterB!=iterE;iterB++)
{
cout<<*iterB<<endl;
}
system("pause");
}
Пример поиска
#include <vector>
#include<iostream>
#include<cstdlib>
#include<string>
#include<algorithm>
using namespace std;
void main()
{
vector <int> vec(10);
vector<int>::iterator iter=vec.begin();
int fnd=0;
for(;iter!=vec.end();iter++)
{
cin>>*iter;
}
cout<<"What find?"<<endl;
cin>>fnd;
iter=find(vec.begin(),vec.end(),fnd);
cout<<iter-vec.begin()<<endl;
system("pause");
}
Основные методы Вектора
push_back (element) — добавить элемент в конец vector-а
|
pop_back (element) — удалить последний элемент vector-а
insert (***) — три варианта (перезагрузки метода) вставки в какую либо область в векторе, первый параметр позиция вставки заданная итераторам, остальные указывают на контейнер, или количество и контейнер, или пару итераторов указывающих от какой до какой позиции из другого контейнера взять данные.
erase (iterator или iterator от, и до) — удаляет элемент или последовательность элементов из vector-а
begin () — возвращает итератор, указывающий на начало коллекции.
end () — возвращает итератор, указывающий на конец коллекции. При этом он указывает не самый последний элемент, а на воображаемый элемент за последним.
at (index) — метод доступа, к элементам коллекции, в отличии от оператора [], проверяет выход из-за границ коллекции, и в случаи чего генерит исключение.
clear () — удаляет все элементы коллекции, при этом если в нем содержаться объекты классов вызывает их деструкторы.
Операции с последовательными контейнерами
Функция-член push_back() позволяет добавить единственный элемент в конец контейнера.
Для вставки элемента в начало контейнера можно использовать:
vector< string > svec;
string spouse("Beth");
svec.insert(svec.begin(), spouse);
Первый параметр функции-члена insert() (итератор, адресующий некоторый элемент контейнера) задает позицию, а второй – вставляемое перед этой позицией значение. В примере выше элемент добавляется в начало контейнера.
Вторая форма функции-члена insert() позволяет вставить указанное количество одинаковых элементов, начиная с определенной позиции. Например, если мы хотим добавить десять элементов Anna в начало вектора, то должны написать:
|
vector<string> svec;
string anna("Anna");
svec.insert(svec.begin(), 10, anna);
insert() имеет и третью форму, помогающую вставить в контейнер несколько элементов. Допустим, имеется следующий массив:
string sarray[4] = { "quasi", "simba", "frollo", "scar" };Мы можем добавить все его элементы или только некоторый диапазон в наш вектор строк:
svec.insert(svec.begin(), sarray, sarray+4);
svec.insert(svec.begin() + svec.size()/2,sarray+2, sarray+4);
Такой диапазон отмечается и с помощью пары итераторов
// вставляем элементы svec
// в середину svec_two
svec_two.insert(svec_two.begin() + svec_two.size()/2,
svec.begin(), svec.end());