|
Программирование >> Немодифицирующие последовательные алгоритмы
Программа выводит следующий текст: New logical contents of array a: 3 4 3 4 5 3 Вместо использования операции сравнения на равенство мы можем задать любой бинарный предикат, воспользовавшись вторым вариантом алгоритма с тем же именем, который принимает предикат в качестве третьего аргумента. Следующая программа использует этот вариант алгоритма unique, чтобы удалить каждый из элементов вектора, который больше предыдущего на единицу: unique2.cpp: Второй из алгоритмов unique. Удалить v[i+l], если он равен v[i] + 1. ttinclude <iostream> ttinclude <vector> ttinclude <algorithm> using namespace std; bool onehigher(int x, int у){return x + 1 == y;) int mainO { int a[10] = {3, 4, 3, 1, 6, 7, 7, 7, 8, 4); vector<int> v; vector<int>::iterator i; for (int k=0; k<10; k++) v.push back(a[k]); двусторонняя очередь или список. Кстати, если возникает необходимость использовать этот алгоритм для списков, лучше воспользоваться функцией-членом unique класса list, поскольку она более эффективна. Напомним, что эту функцию-член мы рассматривали в разделе 3.5. Алгоритм unique возвращает новый логический конец данных, как показывает следующая программа: uniquel.cpp: Первый из алгоритмов unique. #include <iostream> #include <algorithm> using namespace std; int mainO { int a[10] = {3, 4, 3, 3, 4, 4, 5, 3, 3, 3}, *p; p = unique(a, a+10); cout << New logical contents of array a:\n ; copy(a, p, ostream iterator<int>(cout, )); cout endl; return 0; i = unique (v.beginO , v.endO, onehigher) ; cout << Logical contents of v:\n ; copy(v.begin0, i, ostream iterator<int>(cout, )); cout \nv.size() = v.sizeO << endl; return 0; Программа начинает свою работу с помещения значений в вектор v. 3431677784 Поскольку v[i] (= 4) на единицу больше предшествующего элемента v[0], этот элемент будет удален из результата. Та же jacTb постигнет элемент г:[5] (= 7), потому что его предшественник v[A] равен 6. Хотя на первый взгляд может показаться, что значение 8 также не попадет в результат, потому что следует за 7, это не так: после удаления всех элементов, равных 7, 8 окажется после 6 и останется нетронутым, как показывает вывод программы: Logical contents of v: 3 3 1 6 8 4 V.sizeO = 10 Заметим, что размер вектора по-прежнему остается равен 10, но логическое содержание составляет только поддиапазон [v.beginQ, i). Ситуация похожа на массив символов, в котором обычно используется только начальная часть, заканчивающаяся символом \0. Если после вызова unique мы захотим изменить размер вектора, равный usizeQ = 10, в соответствии с его новым логическим размером i - v.beginQ = 6, то можем это сделать с помощью функции-члена erase: V.erase(i, v.end()); Существуют также две функции unique copy, которые похожи на функции unique, за исключением того, что результат их работы копируется в другой контейнер. Мы могли бы использовать эти функции в программе uniquel.cpp следующим образом. Фрагмент vector<int> v; vector<int>::iterator i; for (int k=0; k<10; k++) v.push back(a[k]); i = unique (v.beginO , v.endO, onehigher); можно заменить на более короткий vector<int> v(10,0); vector<int>::iterator i; i = unique copy (a, a+10, v.beginO, onehigher); После такой замены программа будет работать так же, как и приведенная выше версия. Другой вариант функции uniquecopy похож на первую версию unique. Он проверяет последовательные элементы на равенство. Мы можем использовать эту версию в выражении i = unique copy(а, а+10, v.beginO); 7.2.10. Расположить в обратном порядке void reverse (Bidirectionallterator first, Bidirectionallterator last); Outputlterator reverse copy (Bidirectionallterator first, Bidirectionallterator last, Outputlterator result); Напомним, что алгоритм reverse мы обсуждали в разделе 1.10. Алгоритм reversecopy не изменяет заданный диапазон, а помещает элементы в обратном порядке в другой контейнер, как показано в следующей программе: гсору.срр: Алгоритм reverse copy помещает результат в другой контейнер, ttinclude <iostream> ttinclude <algorithm> using namespace std; int mainO { int a[3] = {10, 20, 30), b[3]; reverse copy(a, a+3, b); copy(b, b+3, ostream iterator<int>(cout, )); cout endl; Вывод: 30 20 10 return 0; 7.2.11. Перетасовать void random shuffle (RandomAccessIterator first, RandomAccessIterator last); void random shuffle (RandomAccessIterator first, RandomAccessIterator last, RandomNumberGenerator& rand); Алгоритм random shuffle размещает элементы контейнера в случайном порядке, как показывает следующая программа: rshuffle.cpp: Тасование, ttinclude <iostream>
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |