Удалить все нечетные числа из вектора, используя remove_if() iNewEnd = remove_if (veclntegers.begin (), veclntegers.end (),
[](int element) {return ((element % 2) == 1);} ); // предикат
veclntegers.erase (iNewEnd , veclntegers.end О);
// изменение
// размера
Применение функций удаления и копирования показаны в листинге 23.8.
ЛИСТИНГ 23.8. Функции сору (), copy_if (), remove () И remove_if () ДЛЯ копирования списка в вектор, а также удаления четных и нулевых чисел
#include
#include
2 : #include
#include
using namespace std;
6 : template ctypename T>
void DisplayContents(const T& Input)
8 :
|
{
|
//
|
auto, cbegin: C++11
|
9:
|
for ( auto iElement = Input.cbegin()
|
1 0 :
|
; iElement != Input.cend()
|
//
|
cend(): C++11
|
1 1 :
|
; ++ iElement)
|
|
|
1 2 :
|
cout « *iElement « *
|
|
|
13:
|
|
|
|
cout « "| .Number of elements: " « Input.size() « endl;
}
int main ()
{
list listlntegers;
19:
|
for
|
(int nCount
|
= 0; nCount < 10;
|
++
|
nCount)
|
2 0
|
:
|
|
listlntegers.push_back (nCount);
|
|
2 1
|
:
|
cout
|
« "Source
|
(list) contains:"
|
«
|
endl;
|
2 2 :
|
DisplayContents(listlntegers);
// Инициализировать вектор так, чтобы он содержал вдвое больше
элементов, чем список
vector veclntegers (listlntegers.size () * 2);
27:
auto iLastPos = copy ( listlntegers.begin () // начало исходного
диапазона
29:
|
, listlntegers.end
|
()
|
//
|
конец исходного
|
30:
|
, veclntegers.begin
|
()
|
//
|
диапазона
|
); //
|
начало
|
31:
|
// диапазона
|
назначения
|
|
|
|
|
|
// скопировать нечетные числа из списка в вектор
copy_if ( listlntegers.begin(), listlntegers.end()
, iLastPos
, [](int element){return ((element % 2) == 1);});
37: cout « "Destination (vector) after copy and copy_if:" « endl;
Использование алгоритмов STL
|
533
|
DisplayContents(veclntegers);
// Удалить все экземпляры '0' и изменить размер вектора,
используя erase ()
auto iNewEnd = remove (veclntegers.begin (), veclntegers.end (), 0);
veclntegers.erase (iNewEnd, veclntegers.end ());
43:
// Удалить все нечетные числа из вектора, используя remove_if
iNewEnd = remove_if (veclntegers.begin (), veclntegers.end (),
[](int element) {return ((element % 2) == 1);} );
предикат
veclntegers.erase (iNewEnd , veclntegers.end ()); // изменение
размера
50: cout « "Destination (vector) after remove, remove_if, erase:"
endl;
DisplayContents(veclntegers);
return 0;
}
Результат
Source (list) contains:
|
0123456789
|
| Number of elements: 10
|
Destination (vector)
|
after copy and copy_if:
|
0 1 2 3 4 5 6 7 8 9 1 3 5 7 9 0 0 0 0 0 | Number of elements: 20
|
Destination (vector)
|
after remove, remove_if, erase:
|
2 4 6 8 1 Number of elements: 4
|
Анализ
Применение функции c o p y () представлено в строке 28, где содержимое списка ко пируется в вектор. Ф ункция co p y i f () используется в строке 33, где она копирует все четные числа из исходного диапазона списка l i s t l n t e g e r s в диапазон назначения век
тора v e c l n t e g e r s , начиная с позиции, указанной итератором iL a s tP o s , возвращенным
функцией со р у (). Функция rem ove () представлена в строке 41. Она используется для
избавления вектора v e c l n t e g e r s от всех экземпляров со значением 0. Функция rem ove _ i f () используется в строке 45 для удаления всех нечетных чисел.
ВНИМАНИЕ!
|
В листинге 23.8 показано, что функции remove () и remove_if () возвра
|
|
|
щают итератор, указывающий на новый конец контейнера. Однако контейнер
|
|
veclntegers еще не был изменен. Элементы были удалены алгоритмами
|
|
удаления, и другие элементы были сдвинуты вперед, однако размер вектора
|
|
остался неизменным, т.е. значения в конце остались. Чтобы изменить размеры
|
|
контейнера (и это очень важно, иначе в конце останутся нежелательные значе
|
|
ния), необходимо использовать итератор, возвращенный функцией remove ()
|
|
или remove_if () в последующем вызове метода erase (), как показано в
|
|
строках 42 и 48.
|
534 ЗАНЯТИЕ 23. Алгоритмы библиотеки STL
Замена значений и элементов по заданному условию
Алгоритмы r e p l a c e () и r e p l a c e _ i f () библиотеки STL позволяют заменить в кол лекции элементы, которые соответствуют определенному значению или удовлетворяют за данному условию соответственно. Функция r e p l a c e () заменяет элементы на основании значения, возвращаемого оператором сравнения (==):
cout « "Using 'std::replace' to replace value 5 by 8" « endl; replace (veclntegers.begin (), veclntegers.end (), 5, 8);
Функция r e p l a c e _ i f () ожидает определенный пользователем унарный предикат, ко торый возвращает значение t r u e для каждого значения, подлежащего замене:
cout « "Using 'std::replace_if' to replace even values by -1" « endl; replace_if (veclntegers.begin (), veclntegers.end ()
, [](int element) {return ((element % 2) == 0); }, -1);
Применение этих функций показано в листинге 23.9.
ЛИСТИНГ 23.9. Использование функций replace () и replace_if ()
для замены значений в определенном диапазоне____________________________________________
#include
#include
#include
using namespace std;
template ctypename T>
void DisplayContents(const T& Input)
{
for ( auto iElement = Input.cbegin() // auto, cbegin: С++11
9: ; iElement != Input.cend() // cend(): C++11
; ++ iElement)
11: cout « *iElement « ' ';
1 2 :
cout « "| Number of elements: " « Input.size() « endl;
}
int main ()
{
vector veclntegers (6);
18:
// заполнить сначала 3 элемента значением 8, а // последние 3 значением 5
fill (veclntegers.begin (), veclntegers.begin () + 3, 8);
21: fill_n (veclntegers.begin () + 3, 3, 5);
2 2 :
// переупорядочить контейнер
random_shuffle (veclntegers.begin (), veclntegers.end ());
cout « "The initial contents of the vector are: " « endl;
DisplayContents(veclntegers);
28:
29: cout « endl « "Using 'std::replace' to replace value 5 by 8"
endl;
3 0 : replace (veclntegers.begin (), veclntegers.end (), 5, 8);
|
|
|
|
|
|
Использование алгоритмов STL
|
535
|
3 1 :
|
|
Do'stlaringiz bilan baham: |