Программирование >>  Немодифицирующие последовательные алгоритмы 

1 ... 54 55 56 [ 57 ] 58 59 60 ... 78


Программа выводит следующий текст:

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>



1 ... 54 55 56 [ 57 ] 58 59 60 ... 78

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика