|
Программирование >> Немодифицирующие последовательные алгоритмы
Следующая программа показывает, как это делается, удаляя все элементы, равные 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;
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |