Операции с последовательными контейнерами




Итераторы

Итератор предоставляет обобщенный способ перебора элементов любого контейнера – как последовательного, так и ассоциативного. Пусть 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());



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2019-04-04 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: