Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
STL5 / lab5-algorithms / lab5-algorithm-sort.doc
Скачиваний:
18
Добавлен:
10.04.2015
Размер:
113.15 Кб
Скачать

Алгоритмы поиска

Алгоритмы двоичного поиска вместо итераторов произвольного доступа (RandomAccessIterator) используют итераторы последовательного доступа (ForwardIterator). При использовании таких итераторов число выполняемых сравнений приблизительно равно длине последовательности. В случае использования итераторов произвольного доступа количество сравнений будет равно логарифму от длины последовательности. Для сравнения элементов между собой как и в алгоритмах сортировки используется либоoperator< либо явно заданны критерий сравненияcompare

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

Нижняя граница (lower_bound)

template <class ForwardIterator, class T>

ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last,

const T& value);

template <class ForwardIterator, class T, class Compare>

ForwardIterator lower_bound(ForwardIterator first,

ForwardIterator last, const T& value, Compare comp);

Алгоритм lower_boundнаходит первую позицию, в которую элемент со значениемvalueможет быть вставлен без нарушения упорядоченности последовательности.lower_boundвозвращает самый «ближний к началу последовательности» итераторiв диапазоне[first, last)такой, что для любого итератораj в диапазоне[first, i)выполняются следующие соответствующие условия:*j < valueилиcomp(*j, value) == true. Проще говоря, значения всех элементов, стоящих в последовательности до позицииi, меньше чемvalue, а значения последующих элементов больше или равны value.Делается максимумlog(last - first) + 1сравнений. Также не стоит забывать о том, что этот алгоритм (как иupper_bound) возвращает итератор на элемент, где должно было бы находиться значениеvalue, при этом в позиции, указываемой итератором, может находиться элемент со значением, не равным заданному.

Верхняя граница (upper_bound)

template <class ForwardIterator, class T>

ForwardIterator upper_bound(ForwardIterator first,

ForwardIterator last, const T& value);

template <class ForwardIterator, class T, class Compare>

ForwardIterator upper_bound(ForwardIterator first,

ForwardIterator last, const T& value, Compare comp);

Алгоритм upper_boundнаходит последнюю позицию, в которуюvalueможет быть вставлено без нарушения упорядочения.upper_boundвозвращает самый «дальний от начала последовательсности» итераторiв диапазоне[first, last)такой, что для любого итератораjв диапазоне[first, i)выполняются следующие соответствующие условия:!(value < *j)илиcomp(value, *j) == false. Отличие от предыдущего алгоритма состоит в том, что все элементы, значение которых также равноvalue (если таковые вообще имеются), теперь размещаются перед, а не после данного элемента. Делается максимумlog(last - first) + 1сравнений.

Область вставки (equal_range)

template <class ForwardIterator, class T>

pair<ForwardIterator, ForwardIterator> equal_range(ForwardIterator first,

ForwardIterator last, const T& value);

template <class ForwardIterator, class T, class Compare>

pair<ForwardIterator, ForwardIterator> equal_range(ForwardIterator first,

ForwardIterator last, const T& value, Compare comp);

Алгоритм equal_range находит самый большой поддиапазон [i, j) такой, что значение может быть вставлено по любому итератору k в нём. k удовлетворяет соответствующим условиям: !(*k < value) && !(value < *k) или comp(*k, value) == false && comp(value, *k) == false. Данный алгоритм возвращает пару итераторов, первый из которых эквивалентен результату действияlower_bound, а второй -upper_bound. Эти итераторы ограничивают последовательность элементов со значениями, равнымиvalue.Таким образом, после работы алгоритма весьма просто провести проверку, существует ли в последовательности элемент со значением, равным искомому. Нужно сопоставить полученные итераторы – если они равны, то была возвращена пустая подпоследовательность и, следовательно, элемента с заданным значением в исходной последовательности нет. При работе алгоритма делается максимум2*log(last - first) + 1 сравнений.

Пример использования, equal_range, lower_bound и upper_bound.

#include <algorithm>

#include <vector>

#include <iostream>

using namespace std;

int main()

{

// Вспомогательный массив

int ary[] = {4, 5, 1, 3, 2, 3, 2, 5, 1, 2, 4, 3, 4, 1, 5 };

vector<int> v1(ary,ary+sizeof(ary)/sizeof(ary[0]));

vector<int>::iterator i;

// Выведем исходное содержимое вектора на экран

for (i=v1.begin(); i!=v1.end(); ++i)

cout << *i << " ";

cout << endl;

// Отсортируем v1

sort (v1.begin(),v1.end());

// И снова выведем содержимое v1 на экран

for (i=v1.begin(); i!=v1.end(); ++i) cout << *i << " ";

cout << endl;

// Найдем нижнюю и верхнюю границы для 3

vector<int>::iterator lower_bnd = lower_bound(v1.begin(),v1.end(),3);

vector<int>::iterator upper_bnd = upper_bound(v1.begin(),v1.end(),3);

pair <vector<int>::iterator,vector<int>::iterator> range;

range = equal_range (v1.begin(),v1.end(),3);

// выведем полученные результаты

cout << "*lower_bnd == " << *lower_bnd <<endl;

cout << "*upper_bnd ==" << *upper_bnd <<endl;

cout << "*range.first and *range.second == " << *range.first << ":"

<< *range.second << ")" <<endl;

cout << "distance(v1.begin(),lower_bnd) == "

<< distance(v1.begin(),lower_bnd) <<endl;

cout << "distance(v1.begin(),upper_bnd) == "

<< distance(v1.begin(),upper_bnd) <<endl;

cout << "distance(v1.begin(),range.first) == "

<< distance(v1.begin(),range.first) <<endl;

cout << "distance(v1.begin(),range.second) == "

<< distance(v1.begin(),range.second) <<endl;

return 0;

}

Вывод программы:

4 5 1 3 2 3 2 5 1 2 4 3 4 1 5

1 1 1 2 2 2 3 3 3 4 4 4 5 5 5

*lower_bnd == 3

*upper_bnd ==4

*range.first and *range.second == 3:4)

distance(v1.begin(),lower_bnd) == 6

distance(v1.begin(),upper_bnd) == 9

distance(v1.begin(),range.first) == 6

distance(v1.begin(),range.second) == 9

Соседние файлы в папке lab5-algorithms