На этом шаге рассмотрим алгоритмы.
Алгоритмы определены в заголовочном файле QtAlgorithms и предоставляют операции, применяемые к контейнерам, например: сортировка, поиск, преобразование данных и т. д. Следует отметить, что алгоритмы реализованы не в виде методов контейнерных классов, а в виде шаблонных функций, что позволяет использовать их как для любого контейнерного класса Tulip, так и для обычных массивов. Например, для копирования элементов из одного массива в другой можно задействовать алгоритм qCopy():
QList<QString> list1; list1 << "Turbo Pascal" << "Borland Delphi" << "Borland C++"; //копируем элементы списка, начиная с первого, //в начало вектора QVector<QString> lcopy(3); qCopy(list1.begin(), list1.end(), lcopy.begin()); qDebug() << lcopy; //копируем элементы списка,начиная со второго, //в четвертый элемент вектора QVector<QString> lcopy1(8); qCopy(list1.begin()+1, list1.end(), lcopy1.begin()+3); qDebug() <<l copy1;
Рис.1. Результат копирования списка
При копировании контейнеров важно убедиться, что целевой контейнер имеет размер, достаточный для размещения копии. В нашем примере мы позаботились о том, чтобы целевой контейнер имел такой же размер, как контейнер-источник.
В табл. 1 перечислены все предоставляемые алгоритмы Tulip. Qt предоставляет только самые основные алгоритмы, но если их вдруг окажется недостаточно, всегда можно воспользоваться алгоритмами STL.
Двоичный поиск заданных значений | |
Копирование элементов, начиная с первого | |
Копирование элементов, начиная с последнего | |
Подсчет элементов контейнера | |
Удаление всех элементов. Необходимо, чтобы элементы контейнера не были константными указателями | |
Сравнение. Необходимо, чтобы для размещенных объектов был определен оператор == | |
Присваивает всем элементам контейнера заданное значение | |
Поиск заданных значений | |
Нахождение первого элемента со значением, большим либо равным заданного | |
Нахождение первого элемента со значением, строго большим заданного | |
Сортировка элементов | |
Сортировка элементов с сохранением порядка следования равных элементов | |
Перемена двух значений местами |
Сортировка
Сортировку осуществляет функция-алгоритм qSort(). Для сортировки необходимо, чтобы к типам элементов контейнера можно было применить операторы сравнения. Например, для QString эти операторы доступны. Произведем сортировку для списка с элементами QString:
QList<QString> list1; QList<QString> list2; list1 << "Turbo Pascal" << "Borland Delphi" << "Borland C++"; list2 << "Matlab" << "Borland Delphi" << "MathCad"; //сортируем списки qSort(list1); qSort(list2); //выводим отсортированные списки на экран qDebug() << "Sorted list 1 = " << list1; qDebug() << "Sorted list 2 = " << list2;
На экране мы увидим следующее:
Рис.2. Результат сортировки списков
Поиск
За поиск элементов отвечает функция-алгоритм qFind(). Эта функция возвращает итератор, установленный на первый найденный элемент или на end(), если элемент не найден.
//итератору присваиваем значение функции //поиска элемента в списке QList<QString>::iterator it = qFind(list1.begin(), list1.end(), "Turbo Pascal"); //если элемент найден, то if (it != list1.end()) { //выводим его на экран qDebug() << "Found = " << *it; } //иначе else { //выводим сообщение, что такого элемента в списке нет qDebug() << "Not Found"; }
На экране мы увидим следующее:
Рис.3. Результат поиска элемента в списке
Сравнение
Иногда возникает необходимость в сравнении содержимого контейнеров различных типов. Это можно осуществить при помощи функции-алгоритма qEqual(). Как и в случае сортировки, для элементов контейнера должны быть применимы операторы сравнения.
list1 << "Turbo Pascal" << "Borland Delphi" << "Borland C++"; qDebug() << "list1 = " << list1; QVector<QString> lcopy(3); qCopy(list1.begin(), list1.end(), lcopy.begin()); qDebug() << "lcopy = " << lcopy; //сравниваем список list1 и вектор lcopy /(содержат одинаковые элементы) qDebug() << "Equal list1 & lcopy = " << qEqual(list1.begin(),list1.end(),lcopy.begin()); QVector<QString> lcopy1(8); qCopy(list1.begin()+1, list1.end(), lcopy1.begin()+3); qDebug() << "lcopy1 = " << lcopy1; //сравниваем список list1 и вектор lcopy1 /(содержат различные элементы) qDebug() << "Equal list1 & lcopy1 = " << qEqual(list1.begin(),list1.end(),lcopy1.begin());
На экране вы увидите:
Рис.4. Результат сравнения элементов списка и вектора
Файлы приложения можно взять здесь.
На следующем шаге рассмотрим произвольный тип QVariant.