Чтение онлайн

на главную

Жанры

Эффективное использование STL
Шрифт:

Timestamp ageLimit;

vt.erase(vt.begin, lower_bound(vt.begin, // Удалить из vt все объекты,

 vt.end, // предшествующие значению

 ageLimit)); // ageLimit

Слегка изменим условия задачи. Допустим, требуется удалить все объекты, предшествующие или равные

ageLimit
. Для этого необходимо найти первый объект после
ageLimit
. Для решения задачи идеально подходит алгоритм
upper_bound
:

vt.erase(vt.begin, upper_bound(vt.begin, //
Удалить из vt все объекты,

 vt.end, // предшествующие или

 ageLimit)); // эквивалентные ageLimit

Алгоритм

upper_bound
также часто применяется при вставке в сортированные интервалы, когда объекты с эквивалентными значениями должны следовать в контейнере в порядке вставки. Рассмотрим сортированный список объектов
Person
, в котором объекты сортируются по имени:

class Person {

public:

 …

 const string& name const;

 …

}

struct PersonNameLess:

 public binary_function<Person, Person, bool> { // См. совет 40

 bool operator(const Person& lhs, const Person& rhs) const {

return lhs.name < rhs.name;

 }

};

list<Person> lp;

lp.sort(PersonNameLess); // Отсортировать lp по критерию

// PersonNameLess

Чтобы список сортировался требуемым образом (по имени, с хранением эквивалентных имен в порядке вставки), можно воспользоваться алгоритмом

upper_bound
для определения позиции вставки:

Person newPerson;

lp.insert(upper_bound(lp.begin, // Вставить newPerson за последним

 lp.end, // объектом lр, предшествующим

 newPerson, // или эквивалентным newPerson

 PersonNameLess), newPerson);

Приведенное решение работоспособно и достаточно удобно, но не стройте иллюзий насчет того, что оно каким-то волшебным способом обеспечивает поиск точки вставки в контейнер

list
с логарифмической сложностью. Как объясняется в совете 34, при работе с
list
поиск занимает линейное время, но при этом выполняется логарифмическое количество сравнений.

До настоящего момента рассматривался только случай, когда поиск осуществляется в интервале, определяемом парой итераторов. Довольно часто работать приходится со всем контейнером вместо интервала. В этом случае необходимо различать последовательные и ассоциативные контейнеры. Для стандартных последовательных контейнеров (

vector
,
string
,
deque
и
list
) достаточно следовать рекомендациям, изложенным ранее, используя начальный и конечный итераторы контейнера для определения интервала.

Со стандартными ассоциативными контейнерами (

set
,
multiset
,
map
,
multimap
)
дело обстоит иначе. В них предусмотрены функции поиска, которые по своим возможностям обычно превосходят алгоритмы STL Превосходство функций контейнеров перед алгоритмами подробно рассматривается в совете 44; если говорить кратко — они быстрее работают и ведут себя более последовательно. К счастью, имена функций обычно совпадают с именами соответствующих алгоритмов, поэтому там, где речь идет об алгоритмах
count
,
find
,
lower_bound
,
upper_bound
и
equal_range
, при поиске в ассоциативных контейнерах вместо них достаточно выбрать одноименную функцию. К сожалению, для алгоритма
binary_search
парной функции не существует. Чтобы проверить наличие значения в контейнере
set
или
map
, воспользуйтесь идиоматической ролью
count
как условия проверки:

set<Widget> s; // Создать множество, заполнить данными

Widget w; // Искомое значение

if (s.count(w)) { // Существует значение, эквивалентное w

 …

} else {

 … // Эквивалентное значение не существует

}

При проверке присутствия значений в контейнерах

multiset
или
multimap
функция
find
обычно превосходит
count
, поскольку она останавливается при обнаружении первого объекта с искомым значением, а функция count в худшем случае просматривает все элементы контейнера.

Тем не менее при подсчете объектов в ассоциативных контейнерах

count
надежно занимает свою нишу. В частности, вызов
count
предпочтительнее вызова
equal_range
с последующим применением
distance
к полученным итераторам. Во-первых, само название функции подсказывает ее смысл — слово
count
означает «подсчет». Во-вторых,
count
упрощает работу программиста, поскольку ему не приходится создавать пару и передавать ее компоненты при вызове
distance
. В-третьих,
count
работает чуть быстрее.

Попробуем подвести итог всему, о чем говорилось в настоящем совете. Информация собрана в следующей таблице.

Поделиться:
Популярные книги

Усадьба леди Анны

Ром Полина
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Усадьба леди Анны

Чужая дочь

Зика Натаэль
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Чужая дочь

Светлая тьма. Советник

Шмаков Алексей Семенович
6. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Светлая тьма. Советник

Двойник Короля

Скабер Артемий
1. Двойник Короля
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Двойник Короля

Его нежеланная истинная

Кушкина Милена
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Его нежеланная истинная

Последний Паладин. Том 2

Саваровский Роман
2. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 2

Измена. Наследник для дракона

Солт Елена
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Измена. Наследник для дракона

Идеальный мир для Лекаря 9

Сапфир Олег
9. Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
6.00
рейтинг книги
Идеальный мир для Лекаря 9

Мастер темных Арканов

Карелин Сергей Витальевич
1. Мастер темных арканов
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Мастер темных Арканов

Адвокат империи

Карелин Сергей Витальевич
1. Адвокат империи
Фантастика:
городское фэнтези
попаданцы
фэнтези
5.75
рейтинг книги
Адвокат империи

Кодекс Охотника. Книга XXI

Винокуров Юрий
21. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XXI

Вечный. Книга II

Рокотов Алексей
2. Вечный
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Вечный. Книга II

Законы Рода. Том 3

Flow Ascold
3. Граф Берестьев
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 3

Наследник

Шимохин Дмитрий
1. Старицкий
Приключения:
исторические приключения
5.00
рейтинг книги
Наследник
Алгоритм Функция контейнера
Что вы хотите узнать Несортированный интервал Сортированный интервал Для set и map Для multiset и multimap
Присутствует ли заданное значение? find binary_search count find
Присутствует ли заданное значение? И если присутствует, то где находится первый объект с этим значением? find equal_range find find или lower_bound (см. ранее)