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

на главную - закладки

Жанры

Стандарты программирования на С++. 101 правило и рекомендация

Александреску Андрей

Шрифт:

Алгоритм

lower_bound
возвращает итератор, указывающий на первый подходящий элемент (если таковой имеется) или на позицию, где он мог бы быть (если такого элемента нет); последнее полезно для поиска верного места для вставки новых значений в отсортированную последовательность. Алгоритм
upper_bound
возвращает итератор, указывающий на элемент, следующий за последним найденным элементом (если таковой имеется), т.е. на позицию, куда можно добавить следующий эквивалентный элемент; это полезно при поиске правильного места для вставки новых значений в отсортированную последовательность, чтобы поддерживать упорядоченность,
при которой равные элементы располагаются в последовательности в порядке их вставки.

Для сортированных диапазонов в качестве быстрой версии

count(first, last, value);
лучше использовать пару вызовов:

p = equal_range(first, last, value);

distance(p.first, p.second);

При поиске в ассоциативном контейнере лучше использовать вместо алгоритмов-не членов функции-члены с тем же именем. Функции-члены обычно более эффективны; например, функция-член

count
выполняется за логарифмическое время (так что, кстати, нет никаких оснований заменять ее вызовом
equal_range
с последующим distance, что имеет смысл для функции count, не являющейся членом).

Ссылки

[Austern99] §13.2-3 • [Bentley00] §13 • [Meyers01] §34, §45 • [Musser01] §22.2 • [Stroustrup00] §17.1.4.1, §18.7.2

86. Пользуйтесь правильным алгоритмом сортировки

Резюме

При сортировке вы должны четко понимать, как работает каждый из сортирующих алгоритмов, и использовать наиболее дешевый среди тех, которые пригодны для решения вашей задачи.

Обсуждение

Вам не всегда требуется полный

sort
; обычно надо меньшее, и весьма редко — большее. В общем случае стандартные алгоритмы сортировки располагаются от наиболее дешевых до наиболее дорогих в следующем порядке:
partition
,
stable_partition
,
nth_element
,
partial_sort
его вариант
partial_sort_copy
),
sort
и
stable_sort
. Используйте наименее дорогой из алгоритмов, которые выполняют необходимую вам работу; применение излишне мощного алгоритма — расточительство.

Время работы алгоритмов

partition
,
stable_partition
и
nth_element
— линейное, что является очень хорошим показателем.

Алгоритмы

nth_element
,
partial_sort
,
sort
и
stable_sort
требуют итераторы произвольного доступа. Вы не можете использовать их при наличии только двунаправленных итераторов (например,
list<T>::iterator
). Если вам нужны данные алгоритмы, но у вас нет итераторов произвольного доступа, вы можете воспользоваться идиомой индексного контейнера: создайте контейнер, поддерживающий итераторы произвольного доступа (например, vector), в котором будут храниться итераторы, указывающие на элементы интересующего вас диапазона, и затем примените к нему более мощный алгоритм с использованием разыменовывающей версии вашего предиката (в которой перед обычным сравнением выполняется разыменование итераторов).

Версии

stable_
… следует
применять только тогда, когда вам необходимо сохранить относительный порядок одинаковых элементов. Заметим, что алгоритмы
partial_sort
и
nth_element
не являются устойчивыми (т.е. они не оставляют одинаковые элементы в том же относительном порядке, в котором они находились до сортировки), и у них нет стандартизированных устойчивых версий. Если вам все же требуется сохранение относительной упорядоченности элементов, вероятно, вам надо использовать
stable_sort
.

Само собой разумеется, не следует прибегать ни к каким алгоритмам сортировки, если вы можете обойтись без них. Если вы пользуетесь стандартным ассоциативным контейнером (

set
/
multiset
или
map
/
multimap
) или адаптером
priority_queue
, и вам требуется только один порядок сортировки, то не забывайте, что элементы в этих контейнерах всегда находятся в отсортированном виде.

Примеры

Пример 1.

partition
. Если вам надо разделить весь диапазон на две группы (группа элементов, удовлетворяющих предикату, за которыми следует группа элементов, предикату не удовлетворяющих), то для этого достаточно воспользоваться алгоритмом
partition
. Это все, что вам надо, чтобы ответить на вопросы наподобие приведенных далее.

• Кто из студентов имеет средний бал не ниже 4.5? Для ответа на этот вопрос можно воспользоваться вызовом

partition(students.begin, students.end, GradeAtLeast(4.5));
, который вернет итератор, указывающий на первого студента, чей средний балл ниже 4.5.

• Какие из товаров имеют вес менее 10 кг? Вызов

partition(products.begin, products.end, WeightUnder(10));
вернет итератор, указывающий на первый товар, вес которого не ниже 10 кг.

Пример 2.

nth_element
. Алгоритм
nth_element
можно использовать для того, чтобы получить один элемент в корректной n-й позиции, в которой он бы находился при полной сортировке всего диапазона, при этом все прочие элементы корректно располагаются до или после этого n-го элемента. Этого достаточно, чтобы ответить на вопросы наподобие следующих.

• Перечислите 20 лучших покупателей. Вызов

nth_element(s.begin, s.begin+19, s.end, SalesRating);
помещает 20 наилучших покупателей в начало контейнера.

• Какое изделие имеет медианное значение качества в данном наборе? Искомый элемент находится в средней позиции отсортированного диапазона. Для его поиска достаточно вызова

nth_element(run.begin, run.begin + run.size/2, run.end, itemQuality);
.

• У какого изделия уровень качества находится на 75-м перцентиле? Искомый элемент находится в позиции, отстоящей на 25% от начала отсортированного диапазона. Для его поиска достаточно вызова

nth_element(run.begin, run.begin+run.size*.25, run.end, ItemQuality);
.

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

Белые погоны

Лисина Александра
3. Гибрид
Фантастика:
фэнтези
попаданцы
технофэнтези
аниме
5.00
рейтинг книги
Белые погоны

Черный дембель. Часть 1

Федин Андрей Анатольевич
1. Черный дембель
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Черный дембель. Часть 1

Лишняя дочь

Nata Zzika
Любовные романы:
любовно-фантастические романы
8.22
рейтинг книги
Лишняя дочь

Темный Лекарь 5

Токсик Саша
5. Темный Лекарь
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Темный Лекарь 5

Последний из рода Демидовых

Ветров Борис
Фантастика:
детективная фантастика
попаданцы
аниме
5.00
рейтинг книги
Последний из рода Демидовых

Чиновникъ Особых поручений

Кулаков Алексей Иванович
6. Александр Агренев
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Чиновникъ Особых поручений

Попаданка в академии драконов 4

Свадьбина Любовь
4. Попаданка в академии драконов
Любовные романы:
любовно-фантастические романы
7.47
рейтинг книги
Попаданка в академии драконов 4

Боги, пиво и дурак. Том 6

Горина Юлия Николаевна
6. Боги, пиво и дурак
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Боги, пиво и дурак. Том 6

Курсант: Назад в СССР 10

Дамиров Рафаэль
10. Курсант
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Курсант: Назад в СССР 10

Сделай это со мной снова

Рам Янка
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Сделай это со мной снова

Болотник 2

Панченко Андрей Алексеевич
2. Болотник
Фантастика:
попаданцы
альтернативная история
6.25
рейтинг книги
Болотник 2

Камень Книга двенадцатая

Минин Станислав
12. Камень
Фантастика:
боевая фантастика
городское фэнтези
аниме
фэнтези
5.00
рейтинг книги
Камень Книга двенадцатая

Небо для Беса

Рам Янка
3. Самбисты
Любовные романы:
современные любовные романы
5.25
рейтинг книги
Небо для Беса

Надуй щеки! Том 4

Вишневский Сергей Викторович
4. Чеболь за партой
Фантастика:
попаданцы
уся
дорама
5.00
рейтинг книги
Надуй щеки! Том 4