// начало исходного диапазона 1
, veclntegersl.end ()
|
()
|
//
|
конец исходного диапазона 1
|
, veclntegers2.begin
|
// начало исходного диапазона 2
|
, dqResultAddition.begin
|
//
|
сохранить результат в
|
, plus () );
|
|
// двухсторонней очереди
|
|
//
|
бинарная функция plus
|
Обе версии алгоритма t r a n s f o r m
|
()
|
всегда присваиваю т результат определенной
|
функции преобразования предоставленному диапазону назначения, в отличие от алгорит ма f o r e a c h (), который воздействует только на один диапазон. Использование алгоритма s t d : : tr a n s f o r m () показано в листинге 23.7.
ЛИСТИНГ 23.7. Использование алгоритма std:: transform ()
унарными и бинарными функциями______________________________________
#include
#include
#include
#include
#include
#include
:
int main ()
8 : {
using namespace std;
1 0 :
string Sample ("THIS is a TEststring!");
cout « "The sample string is: " « Sample « endl;
string strLowerCaseCopy;
strLowerCaseCopy.resize (Sample.size ());
16:
|
transform ( Sample.begin ()
|
//
|
начало исходного диапазона
|
17:
|
18:
|
, Sample.end ()
|
//
|
конец исходного диапазона
|
, strLowerCaseCopy.begin () // начало диапазона
20:
|
, tolower );
|
//
|
назначения
|
//
|
унарная функция
|
2 1 :
22:
|
cout
|
«
|
"Result of 'transform' on the string with 'tolower':"
|
23:
|
cout
|
«
|
endl;
|
« endl « endl;
|
«
|
"\"" « strLowerCaseCopy «
|
24:
|
|
|
|
|
// Два примера векторов целых чисел...
vector veclntegersl, veclntegers2;
for (int nNum = 0; nNum < 10; ++ nNum)
{
veclntegersl.push_back (nNum);
veclntegers2.push_back (10 - nNum);
}
32:
33: //Диапазонназначения для содержания результата сложения
530 ЗАНЯТИЕ 23. Алгоритмы библиотеки STL
deque dqResultAddition (veclntegersl.size ());
transform ( veclntegersl.begin () // начало исходного диапазона 1
37: , veclntegersl.end () // конец исходного диапазона 1
, veclntegers2.begin () // начало исходного диапазона 2
, dqResultAddition.begin () // начало диапазона
40:
|
|
, plus () );
|
//
|
назначения
|
|
//
|
бинарная функция
|
41:
|
cout «
|
"Result of 'transform' using binary function 'plus': "
|
42:
|
|
«
|
endl;
|
|
|
43: cout «endl « "Index Vectorl + Vector2 = Result (in Deque)"
endl;
for(size_t nlndex = 0; nlndex < veclntegersl.size (); ++ nlndex)
{
46: cout « nlndex « " \t " « veclntegersl [nlndex] « "\t+
cout « veclntegers2 [nlndex] « " \t =
cout « dqResultAddition [nlndex] « endl;
}
51:
return 0;
}
Результат
The sample string is: THIS is a TEst string!
Result of using 'transform' with unary function 'tolower' on the string:
"this is a test string!"
Result of 'transform' using binary function 'plus':
Index
|
Vectorl
|
+ Vector2> _ Resi
|
0
|
0
|
+
|
10
|
=
|
10
|
1
|
1
|
+
|
9
|
=
|
10
|
2
|
2
|
+
|
8
|
=
|
10
|
3
|
3
|
+
|
7
|
=
|
10
|
4
|
4
|
+
|
6
|
=
|
10
|
5
|
5
|
+
|
5
|
=
|
10
|
6
|
6
|
+
|
4
|
=
|
10
|
7
|
7
|
+
|
3
|
=
|
10
|
8
|
8
|
+
|
2
|
=
|
10
|
9
|
9
|
+
|
1
|
=
|
10
|
Анализ
Пример демонстрирует обе версии алгоритма s t d : : tr a n s f o r m (): ту, которая воздей ствует на один диапазон с использованием унарной функции to lo w e r (), как показано
строке 20, и вторую, которая воздействует на два диапазона с использованием бинар ной функции p lu s (), как показано в строке 40. Первая версия посимвольно изменяет ре
гистр символов строки на нижний. Если вместо функции to lo w e r () использовать функ
цию to u p p e r (), строка будет переведена в верхний регистр. Другая версия алгоритма s t d : : t r a n s f o r m (), представленная в строках 36 -40, воздействует на элементы, взятые
Использование алгоритмов STL
|
531
|
из двух исходных диапазонов (в данном случае два вектора), и использует бинарный пре дикат в форме функции p lu s () библиотеки STL (определена в заголовке < f u n c tio n a l> ) для их суммирования. Функция s t d : : tr a n s f o r m () получает одну пару за один раз, пере давая их бинарной функции p lu s (), и присваивает результат элементу в диапазоне назна чения, который в данном случае принадлежит контейнеру класса s td :d e q u e . Обратите внимание, что результат в отдельном контейнере сохраняется в демонстрационных целях. Это показывает, насколько хорошо итераторы абстрагируют контейнеры и их реализацию от алгоритмов STL; функция t r a n s f o r m (), будучи алгоритмом, работает с диапазона ми и действительно не обязана знать подробности о контейнере, который реализует эти диапазоны. Так, исходные диапазоны могут быть в векторе, а диапазоны назначения —
двухсторонней очереди, и все будет работать прекрасно, пока допустимы определяющие диапазон границы (предоставляемые как входные параметры функции tr a n s f o r m ()).
Операции копирования и удаления
Библиотека STL предоставляет три очевидных функции копирования: сору (), со р у _ i f () и co p y _ b a ck w a rd (). Функция со р у () способна присвоить содержимое исходного диапазона диапазону назначения в текущем порядке:
auto iLastPos = copy ( listlntegers.begin ()
|
// начало исходного
|
, listlntegers.end
|
()
|
// диапазона
|
//
|
конец исходного
|
, veclntegers.begin
|
() );
|
// диапазона
|
//
|
начало диапазона
|
|
|
//
|
назначения
|
Функция c o p y _ if () копирует элемент, только если предоставленный вами унарный предикат возвращает значение tr u e :
скопировать нечетные числа из списка в вектор copy_if ( listlntegers.begin(), listlntegers.end()
iLastPos
[](int element){return ((element % 2) == 1);});
ПРИМЕЧАНИЕ
Начиная с версии C++11 алгоритм copy_if () находится в пространстве имен std. Если вы используете старый компилятор или несовместимый со стандар том C++И , с его использованием могут возникнуть проблемы.
Функция co p y
b a c k w a rd () присваивает содержимое диапазону назначения в обрат
copy_backward ( listlntegers.begin ()
listlntegers.end ()
veclntegers.end () );
ункция rem o v e (), напротив, удаляет из контейнера элементы, соответствую щ ие определенному значению:
Удалить все экземпляры '0' и изменить размер вектора,
используя erase ()
auto iNewEnd = remove (veclntegers.begin (), veclntegers.end (), 0); veclntegers.erase (iNewEnd, veclntegers.end ());
532 ЗАНЯТИЕ 23- Алгоритмы библиотеки STL
Функция rem ove i f () использует унарный предикат и удаляет из контейнера те эле менты, для которых предикат возвращает значение tr u e :
Do'stlaringiz bilan baham: |