=> Главная База Знаний Qt Обобщенные алгоритмы


Обобщенные алгоритмы

Обобщенные алгоритмы

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

Заголовочный файл STL <algorithm> содержит более полный набор обобщенных алгоритмов. Эти алгоритмы могут использоваться не только с STL-контейнерами, но и с Qt—контейнерами. Если STL доступен на всех ваших платформах, вероятно, нет причин не использовать STL—алгоритмы, когда в Qt отсутствует эквивалентный алгоритм. Далее мы кратко рассмотрим наиболее важные Qt—алгоритмы.

Алгоритм qFind() выполняет поиск конкретного значения в контейнере. Он принимает «начальный» и «конечный» итераторы и возвращает итератор, ссылающийся на первый подходящий элемент, или «конечный» итератор, если нет подходящих элементов. В представленном ниже примере i устанавливается на list.begin() + 1, a j устанавливается на list.end().

QStringList list;

list << "Emma" << "Karl" << "James" << "Mariette";

QStringList::iterator i = qFind(list.begin(), list.end(), "Karl");

QStringList::iterator j = qFind(list.begin(), list.end(), "Petra");

Алгоритм qBinaryFind() выполняет поиск подобно алгоритму qFind(), за исключением того, что он предполагает упорядоченность элементов в возрастающем порядке и использует двоичный поиск в отличие от линейного поиска в qFind().

Алгоритм qFill() заполняет контейнер конкретным значением:

QLinkedList<int> list(10);

qFill(list.begin(), list.end(), 1009);

Как и другие алгоритмы, основанные на применении итераторов, qFill() может выполняться для части контейнера, если соответствующим образом установить аргументы. В следующем фрагменте программного кода первые пять элементов вектора инициализируются значением 1009, а последние пять элементов — значением 2013:

QVector<int> vect(10);

qFill(vect.begin(), vect.begin() + 5, 1009);

qFill(vect.end() - 5, vect.end(), 2013);

Алгоритм qCopy() копирует значения одного контейнера в другой.

QVector<int> vect(list.count());

qCopy(list.begin(), list.end(), vect.begin());

Алгоритм qCopy() может также использоваться для копирования элементов в рамках одного контейнера, если исходный диапазон и целевой диапазон не перекрываются. В следующем фрагменте программного кода мы заменяем последние два элемента списка первыми двумя элементами:

qCopy(list.begin(), list.begin() + 2, list.end() - 2);

Алгоритм qSort() сортирует элементы контейнера в порядке их возрастания.

qSort(list.begin(), list.end());

По умолчанию qSort() использует оператор < для сравнения элементов. Для сортировки элементов по убыванию передайте qGreater<T>() в качестве третьего аргумента (здесь T — тип элемента контейнера):

qSort(list.begin(), list.end(), qGreater<int>());

Мы можем использовать третий параметр для определения пользовательского критерия сортировки. Например, ниже приводится функция сравнения «меньше, чем», которая выполняет сравнение строк QString без учета регистра:

bool insensitiveLessThan(const QString &str1, const QString &str2)

{

return str1.toLower() < str2.toLower();

}

Тогда вызов qSort() будет таким:

QStringList list;

qSort(list.begin(), list.end(), insensitiveLessThan);

Алгоритм qStableSort() аналогичен qSort(), за исключением того, что он гарантирует сохранение порядка следования одинаковых элементов. Этот алгоритм стоит применять в тех случаях, когда критерий сортировки учитывает только часть значения элемента и пользователь видит результат сортировки. Мы использовали qStableSort() в главе 4 для реализации сортировки в приложении Электронная таблица.

Алгоритм qDeleteAll() вызывает оператор delete для каждого указателя, хранимого в контейнере. Он имеет смысл только для контейнеров, в качестве элементов которых используются указатели. После вызова этого алгоритма элементы по-прежнему присутствуют в контейнере, и для их удаления используется функция clear(). Например:

qDeleteAll(list);

list.clear();

Алгоритм qSwap() выполняет обмен значений двух переменных. Например:

int x1 = line.x1();

int x2 = line.x2();

if (x1 > x2)

qSwap(x1, x2);

Наконец, заголовочный файл <QtGlobal>, который включается в любой другой заголовочный файл Qt, содержит несколько полезных определений, в том числе функцию qAbs(), которая возвращает абсолютное значение аргумента, и функции qMin() и qMax(), которые возвращают максимальное или минимальное значение двух значений.