Базовые алгоритмы Qt 4 (Qt 4's Generic Algorithms)
![](https://style.bubooker.vip/templ/izobr/18_pl.png)
Шрифт:
Qt предоставляет ряд алгоритмов на основе шаблона, которые реализуют самые полезные алгоритмы STL, начиная с версии 2. В этой статье, мы рассмотрим некоторые из алгоритмов, предлагаемых в Qt 4 <QtAlgorithms>.
Qt предоставляет собственные алгоритмы потому, что некоторые платформы (например, embedded Linux) не предоставляет реализацию STL. Алгоритмы используются внутри Qt и доступны его пользователям.
Возможно смешивание реализаций STL и Qt контейнеров и алгоритмов. Например, вы можете использовать алгоритм std::find для QList<T>, или qSort для std::vector<T>.
Два вида сортировки
Алгоритмы qSort и qStableSortмогут быть использованы при сортировке элементов QList<T>, QVector<T> или в любом динамическом C++ массиве. С Qt 4, также возможно определить любой оператор сравнения (вместо operator<).
Stable сортировка имеет свойство сохранения порядка похожих элементов при сортировке. Это полезно, когда имеешь дело с элементами, которые сравниваются между собой, даже если они не полностью эквивалентны. Например, если сортируется список адресов по фамилии, можно использовать qStableSort , чтобы сохранить начальный порядок людей с одинаковой фамилией. Обычная сортировка не гарантирует этого.
Линейный и бинарный поиск
Алгоритмы qFind и qBinaryFind в качестве параметров получают итераторы диапазона и значение, а возвращают итератор на элемент, который соответствует данному значению, или "end" итератор, если не найдено ни одного элемента. Алгоритм бинарного поиска намного быстрее чем линейный алгоритм, но он может работать только с сортированными диапазонами.
Если значение встречается более одного раза, qFind вернет итератор на первый элемент, тогда как qBinaryFind на произвольный.
Для большей гибкости, Qt 4 предоставляет qLowerBound и qUpperBound. Как и qBinaryFind, они работают с сортированным диапазоном. Если значение найдено, qLowerBound вернет итератор на первый найденный элемент, а qUpperBound вернет итератор, указывающий на следующий за последним элемент. Если значение не найдено, они вернут итератор на позицию, в которую данный элемент может быть вставлен.
Частый пример использования qLowerBound и qUpperBound это проход по всем вхождениям значения:
Пример: статическая Map
В этой секции, мы будем использовать бинарный поиск, для реализации "static const" map. Структура данных полностью хранится в памяти и состоит из пары "фамилия, имя", которые отсортированы по фамилии. По сравнению с использованием QMap или QHash, этот подход экономит память и имеет смысл в высоко оптимизированных приложениях или библиотеках.
Сначала, мы определяем структуру
Затем объявляем наши данные:
Указатель end отмечает конец массива.
Теперь, когда все на месте, реализация contains тривиальна. Так как C++ указатели отвечают критериям STL итераторов произвольного доступа, мы можем использовать их в связке с qBinaryFind.
Функция givenName возвращает имя человека с данной фамилией. Например, если мы передаем в качестве аргумента "Torvalds", мы получаем "Linus"; если мы передаем "Deitel", функция возвращает "Harvey" или "Paul".
Функция givenNames возвращает список людей, принадлежащих определенной семье. Здесь показано использование qLowerBound и qUpperBound.