; ++ iElement)
cout « *iElement « endl;
}
int main ()
{
vector vecNames;
vecNames.push_back ("John Doe");
vecNames.push_back ("Jack Nicholson");
vecNames.push_back ("Sean Penn");
vecNames.push_back ("Anna Hoover");
21
// вставка дубликатов в вектор
vecNames.push_back ("Jack Nicholson");
24
cout « "The initial contents of the vector are:" « endl;
DisplayContents(vecNames);
27
cout « "The sorted vector contains names in the order:" « endl;
sort (vecNames.begin (), vecNames.end ());
DisplayContents(vecNames);
31
32 cout « "Searching for V'John Doe\" using 'binary_search':"
Использование алгоритмов STL
|
537
|
endl;
bool bElementFound = binary_search (vecNames.begin (), vecNames.end (),
34:
|
|
"John Doe");
|
35:
|
if (bElementFound)
|
36:
|
37:
|
cout «
|
"Result: \"John Doe\" was found in the vector!"
|
|
«
|
endl;
|
else
cout « "Element not found " « endl;
// Удаление смежныхдубликатов
auto iNewEnd = unique (vecNames.begin (), vecNames.end ());
vecNames.erase (iNewEnd, vecNames.end ());
44:
45: cout « "The contents of the vector after using 'unique':"
endl;
DisplayContents(vecNames);
return 0;
}
Результат
The initial contents of the vector are:
John Doe
Jack Nicholson
Sean Penn
Anna Hoover
Jack Nicholson
The sorted vector contains names in the order:
Anna Hoover
Jack Nicholson
Jack Nicholson
John Doe
Sean Penn
Searching for "John Doe" using 'binary_search':
Result: "John Doe" was found in the vector!
The contents of the vector after using 'unique':
Anna Hoover
Jack Nicholson
John Doe
Sean Penn
Анализ
Приведенный выше код сначала сортирует вектор vecN am es (строка 29), а затем (стро
ка 33) использует алгоритм b i n a r y _ s e a r c h () для поиска в нем элемента Jo h n Doe.
Точно так же в строке 42 используется алгоритм s t d : :u n iq u e ( ) для удаления смеж ных дубликатов. Обратите внимание, что функция u n iq u e (), как и rem o v e (), не из меняет размер контейнера. Это приводит к сдвигу значений, но не сокращению общего количества элементов. Чтобы избавиться от нежелательных или неизвестных значений
538 ЗАНЯТИЕ 23. Алгоритмы библиотеки STL
в конце контейнера, после вызова функции u n iq u e () всегда следует вызвать функцию v e c t o r :: e r a s e (), используя итератор, возвращенный функцией u n iq u e (), как показано в строках 42 и 43.
ВНИМАНИЕ!
ПРИМЕЧАНИЕ
Такие алгоритмы, как binary_search (), эффективны только в отсортирован ных контейнерах. При использовании этого алгоритма с неотсортированным вектором могут возникнуть нежелательные последствия.
Функция stable_sort () используется точно так же, как функция sort О , которая была представлена ранее. Функция stable_sort () обеспечивает от носительный порядок отсортированных элементов. Поддержка относительного порядка обходится потерей производительности, что следует учитывать, особен но если порядок смежных элементов не является необходимым.
Разделение диапазона
Функция s t d : : p a r t i t i o n () позволяет разделить исходный диапазон на два раздела:
тот, который удовлетворяет унарному предикату, и другой, который не удовлетворяет:
bool IsEven (const int& nNumber)
|
// унарный предикат
|
{
|
((nNumber % 2) == 0);
|
|
return
|
|
}
|
|
|
partition
|
(veclntegers.begin(),
|
veclntegers.end(), IsEven);
|
Однако функция s t d : : p a r t i t i o n
|
() не гарантирует относительный порядок эле
|
ментов в пределах каждого раздела. Когда это важно, следует использовать функцию s t d : : s t a b l e _ p a r t i t i o n ():
stable_partition (veclntegers.begin() , veclntegers.end(), IsEven); В листинге 23.11 показано применение этих алгоритмов.
ЛИСТИНГ 23.11. Использование алгоритмов partition () и stablejpartition ()
для разделения диапазона целых чисел на четные и нечетные значения______________________
#include
#include
#include
using namespace std;
bool IsEven (const int& nNumber)
6 : {
return ((nNumber % 2) == 0);
8 : }
9:
template
void DisplayContents(const T& Input)
12: {
for ( auto iElement = Input.cbegin() // auto, cbegin: C++11
|
|
Использование алгоритмов STL
|
539
|
14:
|
;
|
iElement != In p u t .c en d () / / c e n d ( ) : C++11
|
|
15:
|
;
|
++ iElement)
|
|
cout « *iElement « '
18:
|
cout
|
«
|
"| Number
|
of
|
elem ents:
|
"
|
«
|
I n p u t . s i z e () « endl;
|
19:
|
}
|
|
|
|
|
|
|
|
20:
|
i n t main
|
()
|
|
|
|
|
|
|
2 1 :
|
{
|
|
|
|
|
|
|
|
22:
|
v e c to r v e c ln te g e r s ;
|
|
|
|
23:
|
|
|
|
|
|
|
|
|
24:
|
f o r
|
( in t
|
nNum = 0;
|
nNum < 10;
|
++
|
nNum)
|
25:
|
v ec ln te g ers .p u sh _ b ac k
|
(nNum);
|
|
|
|
26:
|
|
|
|
|
|
|
|
|
27:
|
cout
|
«
|
"The i n i t i a l
|
c o n te n ts :
|
"
|
«
|
endl;
|
D is p la y C o n te n ts (v e c ln te g e rs );
30:
|
v e c to r
|
|
vecCopy
|
(v e c ln te g e rs );
|
31:
|
|
|
|
|
|
32:
|
cout «
|
"The
|
e f f e c t
|
of u sin g
|
p a r t i t i o n ( ):" « endl;
|
33:
|
p a r t i t i o n (v e c ln te g e rs . b e g in
|
(), v e c ln te g e r s . e n d (), IsEven);
|
D is p la y C o n te n ts (v e c ln te g e rs );
36:
|
cout « "The e f f e c t of u sing s t a b l e _ p a r t i t i o n ( ) :"
|
« endl;
|
37:
|
s t a b l e _ p a r t i t i o n (vecCopy.begin (),vecCopy.end (),
|
IsEven);
|
D isplayC ontents(vecC opy);
Результат
The
|
i n i t i a l
|
contents:
|
|
|
|
|
0 1
|
23456789
|
I
|
Number
|
of
|
elements:
|
10
|
The
|
e f f e c t
|
of using
|
p a r t i t i o n ():
|
|
|
0 8
|
26453719
|
I
|
Number
|
of
|
elements:
|
10
|
The
|
e f f e c t
|
of using
|
s t a b le _ p a r titi o n ():
|
|
0 2
|
46813579
|
|
|
Number
|
of
|
elements:
|
10
|
Анализ
Код делит диапазон целых чисел, содержащийся в векторе v e c l n t e g e r s , на четные и нечетные значения. Сначала разделение осущ ествляется с использованием функции s t d : : p a r t i t i o n (), как показано в строке 33, а затем с использованием функции s t a -
b l e _ p a r t i t i o n () в строке 37. Для сравнения пример диапазона v e c l n t e g e r s копиру
ется в вектор vecC opy, первый разделяется с использованием функции p a r t i t i o n (),
а последний — с использованием s t a b l e j p a r t i t i o n (). Различие в результатах исполь
зования функций s t a b l e j p a r t i t i o n () и p a r t i t i o n () вполне очевидно в выводе. А л
горитм s t a b l e j p a r t i t i o n () обеспечивает относительный порядок элементов в каждом
разделе. Обратите внимание, что поддержка этого порядка сказывается на производитель
ности, которая может быть как незначительной, как в данном случае, так и существенной,
в зависимости от типа содержавшихся в диапазоне объектов.
540 ЗАНЯТИЕ 23. Алгоритмы библиотеки STL
Do'stlaringiz bilan baham: |