Базовые алгоритмы Qt 4 (Qt 4's Generic Algorithms)

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

Жанры

Поделиться:

Базовые алгоритмы Qt 4 (Qt 4's Generic Algorithms)

Шрифт:

Qt предоставляет ряд алгоритмов на основе шаблона, которые реализуют самые полезные алгоритмы STL, начиная с версии 2. В этой статье, мы рассмотрим некоторые из алгоритмов, предлагаемых в Qt 4 <QtAlgorithms>.

Qt предоставляет собственные алгоритмы потому, что некоторые платформы (например, embedded Linux) не предоставляет реализацию STL. Алгоритмы используются внутри Qt и доступны его пользователям.

Возможно смешивание реализаций STL и Qt контейнеров и алгоритмов. Например, вы можете использовать алгоритм std::find для QList<T>, или qSort для std::vector<T>.

Это работает потому, что алгоритмы основаны на итераторах STL-стиля, и итераторы контейнеров классов Qt отвечают требованиям STL.

Два вида сортировки

Алгоритмы 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 это проход по всем вхождениям значения:

QStringList list;

QStringList::iterator i, j;

...

i = qLowerBound(list.begin, list.end, value);

j = qUpperBound(list.begin, list.end, value);

 

while (i != j) {

processItem(*i);

++i;

}

Пример: статическая Map

В этой секции, мы будем использовать бинарный поиск, для реализации "static const" map. Структура данных полностью хранится в памяти и состоит из пары "фамилия, имя", которые отсортированы по фамилии. По сравнению с использованием QMap или QHash, этот подход экономит память и имеет смысл в высоко оптимизированных приложениях или библиотеках.

Сначала, мы определяем структуру

для имен, а так же операторы сравнения для поиска вхождения фамилий:

struct Entry {

const char *familyName;

const char *givenName;

};

 

bool operator<(const Entry &entry, const QString &family)

{

return entry.familyName < family;

}

 

bool operator<(const QString &family, const Entry &entry)

{

return family < entry.familyName;

}

Затем объявляем наши данные:

static const int NumEntries = 4;

static const Entry entries[NumEntries] = {

{ "Deitel", "Harvey" },

{ "Deitel", "Paul" },

{ "Jobs", "Steve" },

{ "Torvalds", "Linus" }

};

static const Entry * const end = entries + NumEntries;

Указатель end отмечает конец массива.

bool contains(const QString &family)

{

return qBinaryFind(entries, end, family) != end;

}

Теперь, когда все на месте, реализация contains тривиальна. Так как C++ указатели отвечают критериям STL итераторов произвольного доступа, мы можем использовать их в связке с qBinaryFind.

QString givenName(const QString &family)

{

const Entry *i = qBinaryFind(entries, end, family);

if (i == end)

return "";

return i->givenName;

}

Функция givenName возвращает имя человека с данной фамилией. Например, если мы передаем в качестве аргумента "Torvalds", мы получаем "Linus"; если мы передаем "Deitel", функция возвращает "Harvey" или "Paul".

QStringList givenNames(const QString &family)

{

const Entry *i = qLowerBound(entries, end, family);

const Entry *j = qUpperBound(entries, end, family);

QStringList result;

while (i != j)

result += (i++)->givenName + (" " + family);

return result;

}

Функция givenNames возвращает список людей, принадлежащих определенной семье. Здесь показано использование qLowerBound и qUpperBound.

Книги из серии:

Без серии

Комментарии:
Популярные книги

Огни Эйнара. Долгожданная

Макушева Магда
1. Эйнар
Любовные романы:
любовно-фантастические романы
эро литература
5.00
рейтинг книги
Огни Эйнара. Долгожданная

Real-Rpg. Еретик

Жгулёв Пётр Николаевич
2. Real-Rpg
Фантастика:
фэнтези
8.19
рейтинг книги
Real-Rpg. Еретик

Вперед в прошлое 2

Ратманов Денис
2. Вперед в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 2

Как я строил магическую империю

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

Возвращение Безумного Бога 5

Тесленок Кирилл Геннадьевич
5. Возвращение Безумного Бога
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Возвращение Безумного Бога 5

Ненужная жена

Соломахина Анна
Любовные романы:
любовно-фантастические романы
5.86
рейтинг книги
Ненужная жена

Идеальный мир для Социопата 6

Сапфир Олег
6. Социопат
Фантастика:
боевая фантастика
рпг
6.38
рейтинг книги
Идеальный мир для Социопата 6

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

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

Мимик нового Мира 6

Северный Лис
5. Мимик!
Фантастика:
юмористическая фантастика
попаданцы
рпг
5.00
рейтинг книги
Мимик нового Мира 6

Разбуди меня

Рам Янка
7. Серьёзные мальчики в форме
Любовные романы:
современные любовные романы
остросюжетные любовные романы
5.00
рейтинг книги
Разбуди меня

Новая мама в семье драконов

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

Ты всё ещё моя

Тодорова Елена
4. Под запретом
Любовные романы:
современные любовные романы
7.00
рейтинг книги
Ты всё ещё моя

Разведчик. Заброшенный в 43-й

Корчевский Юрий Григорьевич
Героическая фантастика
Фантастика:
боевая фантастика
попаданцы
альтернативная история
5.93
рейтинг книги
Разведчик. Заброшенный в 43-й

Газлайтер. Том 9

Володин Григорий
9. История Телепата
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Газлайтер. Том 9