|
Программирование >> Немодифицирующие последовательные алгоритмы
int main О { list<int> L; list<int>::iterator i, jl, j2, j; for (int к = 10; к <= 80; к += 10) { L.push back(k); j = L.endO ; if (k == 20) jl = --j; else if (k == 50) j2 = --j; else if (k == 70) i = --j; L. spliced, L, jl, j2); copy(L.begin(), L.end(), ostream iterator<int>(cout, )); cout endl; return 0; Обратим внимание на оператор i = ~j; и подобные ему в этой программе. Мы не можем заменить его на i = j - 1; потому что операторы плюс и минус не определены для двунаправленных итераторов (см. раздел 1.9). Здесь требуется использовать оператор -, так как итератору = L.endQ ссылается на позицию после последнего элемента, который был добавлен с помощью pushjback. Вместо решения с тремя операторами г/мы могли бы использовать алгоритм find, заменив довольно сложный цикл for, приведенный выше, на следующий фрагмент: for (int к = 10; к <= 80; к += 10) L.push back(к); jl = find(L.begin() , L.endO, 20); j2 = find(L.begin() , L.endO, 50); i = find(L.begin() , L.endO, 70); Данный фрагмент вполне приемлем для короткой последовательности, используемой в этой программе, но решение, приведенное в полном примере, более эффективно для очень длинных последовательностей. Стоит вспомнить, что алгоритмы, такие как find, объявлены в заголовке algorithm, поэтому мы могли бы написать iinclude <algorithm> в начале нашей программы. Для ВС5 этот заголовок включается косвенным образом такими заголовками, как vector или list, поэтому мы опустили эту строчку, полагая, что другие современные версии STL ведзгг себя аналогично. Функция-член remove класса list Когда нам требуется удалить все элементы списка с заданным значением, решение в два этапа, использующее алгоритмы remove и erase, рассмотренное в разделе 1.13, является не самым эффективным. Гораздо лучше для этой цели подойдет функция-член remove, определенная для списков. Она объявлена в шаблонном классе list следующим образом: void remove(const Т& value); Эта функция специфична для списков; она не определена как член для векторов и двусторонних очередей. Следующая программа показывает, что remove довольно проста в использовании: remove.срр: Функция-член remove класса list, iinclude <iostream> iinclude <list> using namespace std; void out(const char *s, const list<int> &L) { cout s; copy(L.begin0 , L.endO, ostream iterator<int>(cout, )); cout endl; int mainO { list<int> L; list<int>::iterator new end; L.push back(l); L.push back(4); L.push back(l); L.push back(3); L.push back(l); L.push back(2); out( Initial sequence L:\n , L); L.remove(l); out( After L.remove(1):\n , L); return 0; Вывод программы: Initial sequence L: 14 13 12 After L.remove(l): 4 3 2 Функция-член reverse класса list Класс list определяет также функцию reverse, объявленную следующим образом: void reverse(); Эта функция-член, определенная только для списков, но не для векторов и двусторонних очередей, использует в своих целях устройство списка. Поэтому для списка L предпочтительнее употреблять вызов функции-члена L. reverse О ; нежели вызов алгоритма reverse reverse (L.begin() , L.endO); Функция-член merge класса list Объединение для списков может быть выполнено более эффективно, чем для векторов или двусторонних очередей, поскольку требуется копировать только ссылки, а не сами элементы. Класс list содержит следующее объявление функции-члена merge: void merge(list<T>& x); Приведенная далее программа показывает, как использовать эту функцию: Istmerge.cpp: Объединение списков с помощью функции-члена merge. iinclude <iostream> iinclude <list> using namespace std; void out(const char *s, const list<int> &L) { cout s; copy(L.begin() , L.endO, ostream iterator<int>(cout, )); cout endl; } int mainO { list<int> LI, L2, L3; list<int>::iterator new end; Ll.push back(10); LI.push back(20); Ll.push back(30); L2.push back(15); L2.push back(35); out( Initial sequence Ll:\n , LI); out( Initial sequence L2:\n , L2); LI.merge(L2); out( After LI.merge(L2):\n , LI); return 0; Эта программа выводит: Initial sequence LI: 10 20 30
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |