Алгоритм merge

10 20 30 40 50 60 70 80 90 100

10 20 30 40 80 90 100

10 20 30 40

Итераторы вставки и алгоритм сору

Обратные итераторы

Эта разновидность итераторов (reverse_iterator) очень удобна для прохода по контейнеру от конца к началу. Например, если в программе имеется контейнер vector<double> v1, то для вывода содержимого вектора в обратном порядке можно написать:

vector<double>::reverse_iterator r1;

r1 = v1.rbegin();

while (ri!= v1.rend())

cout << *r1++ << ' ';

Обратите внимание на то, что операция инкремента для такого итератора перемещает указатель на предыдущий элемент контейнера.

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

int main() {

int а[4] = {10, 20, 30, 40};

vector<int> v(a, a + 4);

list<int> L(4); // список из 4 элементов

copy(v.begin(), v.end(), L.begin());

print(L);

return 0;

}

Алгоритм copy при таком использовании, как в этом примере, работает в режиме замещения. Это означает, что 1 -й элемент контейнера-источника замещает 1 -й элемент контейнера-приемника.

Однако этот же алгоритм может работать и в режиме вставки, если в качестве третьего аргумента использовать так называемый итератор вставки.

Итераторы вставки front_inserter(), back_inserter(), inserter() предназначены для добавления новых элементов в начало, конец или произвольное место контейнера.

Покажем использование этих итераторов на следующем примере.

int main() {

int а[4] = {40, 30, 20, 10};

vector<int> va(a, a + 4);

int b[3] = {80, 90, 100};

vector<int> vb(b, b + 3);

int c[3] = {50, 60, 70};

vector<int> vc(c, с + 3);

list<int> L; // пустой список

copy(va.begin(), va.end(), front_inserter(L));

print(L);

copy(vb.begin(), vb.end(), back_inserter(L));

print(L);

list<int>::iterator from = L.begin();

advance(from, 4);

copy(vc.begin(), vc.end(), inserter(L, from));

print(L);

return 0;

}

Результат выполнения программы:

Обратите внимание на следующие моменты:

Первый вызов функции сору осуществляет копирование (вставку) вектора va в список L, причем итератор вставки front_inserter обеспечивает размещение очередного элемента вектора va в начале списка — поэтому порядок элементов в списке изменяется на обратный.

Второй вызов сору пересылает элементы вектора vb в конец списка L благодаря итератору вставки back_inserter, поэтому порядок копируемых элементов не меняется.

Третий вызов сору копирует вектор vc в заданное итератором from место списка L, а именно после четвертого элемента списка. Чтобы определить нужное значение итератора from, мы предварительно устанавливаем его в начало списка, а затем обеспечиваем приращение на 4 — вызовом функции advance().

Алгоритм merge выполняет слияние отсортированных последовательностей для любого типа последовательного контейнера, более того — все три участника алгоритма могут представлять различные контейнерные типы. Например, вектор а и массив b могут быть слиты в список с:

int main() {

int arr[5] = {2, 3, 8, 20, 25};

vector<int> a(arr. arr + 5);

int b[6] = {7, 9, 23, 28, 30, 33};

list<int> c; // Список с сначала пуст

merge(a.begin(). a.end(), b, b + 6, back_inserter(c));

print(c);

return 0;

}

Результат выполнения программы:


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: