Шаг 70.
Библиотека Qt.
Алгоритмы

    На этом шаге рассмотрим алгоритмы.

    Алгоритмы определены в заголовочном файле 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.

Таблица 1. Алгоритмы
Алгоритм
Описание
qBinaryFind()
Двоичный поиск заданных значений
qCopy()
Копирование элементов, начиная с первого
qCopyBackward()
Копирование элементов, начиная с последнего
qCount()
Подсчет элементов контейнера
qDeleteAll()
Удаление всех элементов. Необходимо, чтобы элементы контейнера не были константными указателями
qEqual()
Сравнение. Необходимо, чтобы для размещенных объектов был определен оператор ==
qFill()
Присваивает всем элементам контейнера заданное значение
qFind()
Поиск заданных значений
qLowerBound()
Нахождение первого элемента со значением, большим либо равным заданного
qUpperBound()
Нахождение первого элемента со значением, строго большим заданного
qSort()
Сортировка элементов
qStableSort()
Сортировка элементов с сохранением порядка следования равных элементов
qSwap()
Перемена двух значений местами

    Сортировка

    Сортировку осуществляет функция-алгоритм 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.




Предыдущий шаг Содержание Следующий шаг