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

1 ... 11 12 13 [ 14 ] 15 16 17 ... 78


Следующая программа показывает, как это делается, удаляя все элементы, равные 1, из последовательности:

remove.срр: Алгоритм remove.

#include <iostream> #include <vector> #include <algorithm> #include <iterator> using namespace std;

void out(const char *s, const vector<int> &v) { cout s;

copy(v.begin0, v.end(),

ostream iterator<int>(cout, ));

cout endl;

int main()

{ vector<int> v;

vector<int>::iterator new end;

v.push back(l); v.push back(4); v.push back(l); v.push back(3); v.push back(l); v.push back(2); out( Initial sequence v:\n , v); new end = remove (v. begin () , v.endO, 1); out( After new end = remove(v.begin(),

V.endO , 1) :\n , v) ; V.erase(new end, v.end());

out( After V.erase(new end, v.end()):\n , v); return 0;

Начиная с последовательности {1,4,1,3,1,2}, эта программа логически удаляет элементы, равные 1; остающиеся элементы помещаются в первых

new end - v. begin = 3

элементах, где newjsnd - значение, возвращаемое вызовом функции remove. Остальные три элемента, начиная с позиции newjsnd, затем стираются с помощью функции-члена erase. Вывод этой программы показан ниже:

Initial sequence v: 14 13 12

After new end = remove (v. begin () , v.endO, 1): 4 3 2 3 1 2

After V. erase (new end, v.endO): 4 3 2



Стабильность алгоритма remove иллюстрируется порядком 4, 3, 2 оставшихся элементов - этот порядок совпадает с тем, в котором эти элементы встречались в исходной последовательности. Хотя алгоритм remove применим также и к спискам, для них определена функция-член remove, использование которой предпочтительнее, как мы увидим в разделе 3.5.

Существует также алгоритм remove if, являющийся обобщенной версией remove, точно так же как find if - обобщенная версия find. Следующая программа показывает, как мы можем использовать remove if (опять совместно с функцией-членом erase), чтобы стереть все элементы, меньшие или равные 2:

rm if.cpp: Алгоритм remove if.

#include <iostream> #include <vector> #include <algorithm> #include <iterator>

using namespace std;

void out(const char *s, const vector<int> &v) { cout s;

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

ostream iterator<int>(cout, ));

cout endl;

bool cond(int x) { return x <= 2; }

int main()

{ vector<int> v;

vector<int>::iterator new end;

v.push back(l); v.push back(4); v.push back(l); v.push back(3); v.push back(l); v.push back(2); out( Initial sequence v:\n , v); new end = remove if (v.begin () , v.endO, cond) ; v.erase(new end, v.endO);

out( After erasing all elements <= 2:\n , v); return 0;

Эта программа выдает:

Initial sequence v: 14 13 12

After erasing all elements <= 2: 4 3



Как и remove, алгоритм remove if являйся стабильным, поэтому совпадение порядка следования элементов 4 и 3 в результирующей последовательности с их порядком в исходной последовательности не является случайным.

1.14. Класс auto ptr

После того как размещена динамическая память, нужно внимательно следить за тем, чтобы она была правильно освобождена. Обычно программисты на С используют для этого таИоси/гее, а программисты на С++ используют также new и delete. Первое, о чем необходимо помнить, что после

int *р = new int; int *q = new int[n];

В дальнейшем требуется выполнить следующие операторы:

delete р; delete [] q;

Пара квадратных скобок [] должна использоваться для q, но не для р; несоблюдение этого правила - довольно частая причина ошибок. Другая сложность заключается в необходимости отслеживать копии указателей. Например, если мы напишем

int *а = new int[n], *b; b = a;

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

delete [] а; либо

delete[] b;

HO не оба эти выражения.

В STL определен специальный класс auto ptr, который делает более безопасным использование оператора new в сложных случаях. Функция-член get возвращает указатель на сами данные. Если мы присвоим значение auto ptr а переменной Ь, указателю a.get{) автоматически будет присвоено значение NULL, например:

auto ptr.срр: Данньпу! соответствует только один указатель, ♦include <iostream> ♦include <memory> using namespace std;



1 ... 11 12 13 [ 14 ] 15 16 17 ... 78

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