Home · All Classes · Main Classes · Grouped Classes · Modules · Functions |
<QtAlgorithms> - это заголовочный файл, предоставляющий родовые основанные на шаблонах алгоритмы. Далее...
<QtAlgorithms> - это заголовочный файл, предоставляющий родовые основанные на шаблонах алгоритмы.
С помощью <QtAlgorithms>, Qt предоставляет множество глобальных функций-шаблонов, которые работают с контейнерами и реализуют широко известные алгоритмы. Вы можете использовать эти алгоритмы с любым классом-контейнером, предоставляющим итераторы в стиле STL, включая классы QList, QLinkedList, QVector, QMap и QHash, входящие в Qt.
Эти функции были сделаны наподобие функций, доступных в заголовочном файле STL <algorithm>. Большинство из них имеют эквивалент в STL; например, qCopyBackward() является тем-же самым, что и алгоритм copy_backward() в STL.
Если STL доступно на всех нужных Вам платформах, Вы можете использовать алгоритмы STL вместо их аналогов в Qt. Единственной причиной, по которой Вы можете предпочесть использование алгоритмов STL - это то, что STL предоставляет множество и множество алгоритмов, в то время как Qt предоставляет только важнейшие из них, не делая попыток дублирования функциональности, заложенной в стандарт C++.
Большинство алгоритмов принимают в качестве параметров итераторы итераторы в стиле STL. Алгоритмы считаются родовыми в том смысле, что они не привязаны ни к какому конкретному классу-итератору; Вы можете использовать их с любыми итераторами, отвечающими некоторым требованиям.
Возьмем для примера алгоритм qFill(). В отличие от QVector, QList не имеет функции fill(), которая может использоваться для заполнения списка определенным значением. Если Вам нужны ее функциональные возможности, то можете использовать qFill():
QStringList list; list << "one" << "two" << "three"; qFill(list.begin(), list.end(), "eleven"); // list: [ "eleven", "eleven", "eleven" ]
qFill() принимает итератор начала, итератор конца и значение. В нашем примере мы передаем list.begin() и list.end(), в качестве итераторов начала и конца, но вот так делать не следует:
qFill(list.begin() + 1, list.end(), "six"); // list: [ "eleven", "six", "six" ]
Разные алгоритмы предъявляют разные требования к итераторам, которые они принимают. Например, qFill() принимает два итератора ввода, что является минимальным требованием к типу итераторов. Требования определены для каждого алгоритма. Если передается итератор неверного типа (например, QList::ConstIterator передается в качестве итератора вывода), Вы обязательно получите ошибку компилятора, хотя и необязательно очень информативную.
Некоторые из алгоритмов имеют специальные требования к типам значений, хранящихся в контейнерах. Например, qEqual() требует, чтобы для типа значения был определен operator==(), который используется для сравнения элементов. Точно также, qDeleteAll() требует, чтобы значение имело тип неконстантного указателя (например, QWidget *). Требования к типу значения определены для каждого алгоритма, и компилятор выдаст ошибку, если эти требования не выполняются.
Родовые алгоритмы могут использоваться и в классах, отличных от тех, что предоставляются Qt и STL. Синтаксис итераторов в стиле STL сделан наподобие указателей C++, поэтому возможно использование простых массивов в качестве контейнеров и простых указателей в качестве итераторов. Распространенным является использование qBinaryFind() в совокупности с двумя статическими массивами: один из них содержит список ключей, а другой содержит список ассоциированных значений. Например, в следующем отрывке кода содержимое строки HTML (например, &) будет искаться в массиве name_table и, если вхождение будет найдено, возвращено соответствующее значение Unicode из массива value_table:
QChar resolveEntity(const QString &entity) { static const QLatin1String name_table[] = { "AElig", "Aacute", ..., "zwnj" }; static const ushort value_table[] = { 0x0061, 0x00c1, ..., 0x200c }; int N = sizeof(name_table) / sizeof(name_table[0]); const QLatin1String *name = qBinaryFind(name_table, name_table + N, entity); int index = name - name_table; if (index == N) return QChar(); return QChar(value_table[index]); }
Такой код подходит только для продвинутых пользователей; в большинстве случаев, код на основе QMap или QHash будет работать точно также:
QChar resolveEntity(const QString &entity) { static QMap<QString, int> entityMap; if (!entityMap) { entityMap.insert("AElig", 0x0061); entityMap.insert("Aacute", 0x00c1); ... entityMap.insert("zwnj", 0x200c); } return QChar(entityMap.value(entity)); }
Алгоритмы предъявляют некоторые требования к типам итераторов, которые они принимают, и эти требования определены индивидуально для каждой функции. При несоответствии типа итератора, компилятор выдаст ошибку.
Итератор ввода - это итератор, который может использоваться для последовательного чтения данных из контейнера. Он должен поддерживать операторы: == и != для сравнения двух итераторов, унарный * для получения значения, хранящегося в элементе, и префикс ++ для перемещения к следующему элементу.
Все итераторы контейнеров всех типов Qt (const и не-const) являются итераторами ввода.
Итератор вывода - это итератор, который может использоваться для последовательной записи данных в контейнер или в поток вывода. Он должен поддерживать следующие операторы: унарный * для записи значения (т.е., *it = val) и префикс ++ для перемещения к следующему элементу.
Все неконстантные типы итераторов контейнеров Qt являются итераторами вывода.
Впереднаправленные итераторы - это итераторы удовлетворяющие требованиям, предъявляемым к итераторам ввода и к итераторам вывода.
Все неконтстантые типы итераторов контейнеров Qt являются впереднаправленными итераторами.
Двунаправленные итераторы - это итераторы, удовлетворяющие требованиям, предъявляемым к впереднаправленным итераторам, но, в добавок, поддерживающие префикс --, позволяющий им перемещаться к предыдущему элементу.
Все неконстантные типы итераторов контейнеров Qt являются двунаправленными итераторами.
Последняя категория, итераторы произвольного доступа, - это наиболее мощный тип итераторов. Итераторы этого типа удовлетворяют всем требованиям, предъявляемым к двунаправленным итераторам, и в добавок поддерживает следующие действия:
i += n | перемещение итератора i на n позиций вперед |
i -= n | перемещение итератора i на n позиций назад |
i + n или n + i | возвращает итератор, позиционированный на элемент, расположенный на n позиций после итератора i |
i - n | возвращает итератор, позиционированный на элемент, расположенный на n позиций перед итератором i |
i - j | возвращает количество элементов, расположенных между итераторами i и j |
i[n] | то-же самое, что и *(i + n) |
i < j | возвращает true, если итератор j расположен позади итератора i |
Неконтстантные типы итераторов для QList, QLinkedList и QVector являются итераторами произвольного доступа.
См. также классы-контейнеры и <QtGlobal>.
Выполняет бинарный поиск в диапазоне [begin, end) в возвращает позицию найденного вхождения значения value. Если вхождения value не найдено, возвращает end.
Элементы в диапазоне [begin, end) должны быть отсортированы по возрастанию; см. qSort().
Если существует несколько вхождений искомого значения, то возвращается позиция любого из них. Если Вам нужно более гибкое управление, используйте qLowerBound() или qUpperBound().
Пример:
QVector<int> vect; vect << 3 << 3 << 6 << 6 << 6 << 8; QVector<int>::iterator i = qBinaryFind(vect.begin(), vect.end(), 6); // i == vect.begin() + 2 (или 3, или 4)
Данная функция требует, чтобы для типа элементов (в вышеприведенном примере это QString) был определен operator<().
Пример использования функции см. в подробном описании.
См. также qLowerBound(), qUpperBound() и итераторы произвольного доступа.
Копирует элементы из диапазона [begin1, end1) в диапазон [begin2, ...), сохраняя их порядок.
Элемент, расположенный в позиции begin1, копируется в позицию begin2; элемент, расположенный в позиции begin1 + 1, копируется в позицию begin2 + 1 и т.д.
Пример:
QStringList list; list << "one" << "two" << "three"; QVector<QString> vect1(3); qCopy(list.begin(), list.end(), vect1.begin()); // vect: [ "one", "two", "three" ] QVector<QString> vect2(8); qCopy(list.begin(), list.end(), vect2.begin() + 2); // vect: [ "", "", "one", "two", "three", "", "", "" ]
См. также qCopyBackward(), итераторы ввода и итераторы вывода.
Копирует элементы из диапазона [begin1, end1) в диапазон [..., end2).
Элемент, расположенный в позиции end1 - 1, копируется в позицию end2 - 1; элемент, расположенный в позиции end1 - 2, копируется в позицию end2 - 2 и т.д.
Пример:
QStringList list; list << "one" << "two" << "three"; QVector<QString> vect(5); qCopyBackward(list.begin(), list.end(), vect.end()); // vect: [ "", "", "one", "two", "three" ]
См. также qCopy() и двунаправленные итераторы.
Присваивает параметру n количество вхождений значения value в диапазон [begin, end).
Пример:
QList<int> list; list << 3 << 3 << 6 << 6 << 6 << 8; int countOf6; qCount(list.begin(), list.end(), 6, countOf6); // countOf6 == 3 int countOf7; qCount(list.begin(), list.end(), 7, countOf7); // countOf7 == 0
Данная функция требует, чтобы для типа элементов (в вышеприведенном примере это int) был определен operator==().
См. также итераторы ввода.
С помощью оператора C++ delete удаляет все элементы из диапазона [begin, end). Элементы должны быть указателями (например, QWidget *).
Пример:
QList<Employee *> list; list.append(new Employee("Blackpool", "Stephen")); list.append(new Employee("Twist", "Oliver")); qDeleteAll(list.begin(), list.end()); list.clear();
Обратите внимание на то, что qDeleteAll() не удаляет элементы из контейнера; он лишь вызывает для них delete. В вышеприведенном примере, мы вызываем clear() для удаления элементов из контейнера.
См. также впереднаправленные итераторы.
Данная перегруженная функция-член предоставлена для удобства. Ее поведение аналогично поведению вышеприведенной функции.
То-же самое, что и qDeleteAll(c.begin(), c.end()).
Сравнивает элементы из диапазона [begin1, end1) с элементами из диапазона [begin2, ...). Если все сравниваемые элементы эквивалентны, возвращает true; в противном случае возвращает false.
Пример:
QStringList list; list << "one" << "two << "three"; QVector<QString> vect[3]; vect[0] = "one"; vect[1] = "two"; vect[2] = "three"; bool ret1 = qEqual(list.begin(), list.end(), vect.begin()); // ret1 == true vect[2] = "seven"; bool rec2 = qEqual(list.begin(), list.end(), vect.begin()); // ret2 == false
Данная функция требует, чтобы для типа элементов (в вышеприведенном примере это QString) был определен operator==().
См. также итераторы ввода.
Заполняет диапазон [begin, end) значением value.
Пример:
QStringList list; list << "one" << "two" << "three"; qFill(list.begin(), list.end(), "eleven"); // list: [ "eleven", "eleven", "eleven" ] qFill(list.begin() + 1, list.end(), "six"); // list: [ "eleven", "six", "six" ]
См. также qCopy() и впереднаправленные итераторы.
Возвращает итератор, позиционированный на первое вхождение значения value в диапазон контейнера [begin, end). Если значение value не найдено, возвращает end.
Пример:
QStringList list; list << "one" << "two" << "three"; QStringList::iterator i1 = qFind(list.begin(), list.end(), "two"); // i1 == list.begin() + 1 QStringList::iterator i2 = qFind(list.begin(), list.end(), "seventy"); // i2 == list.end()
Данная функция требует, чтобы для типа элементов (в вышеприведенном примере это QString) был определен operator==().
Если значения в диапазоне отсортированы по возрастанию, то, используя qLowerBound() или qBinaryFind() вместо qFind(), Вы можете получить результат быстрее.
См. также qBinaryFind() и итераторы ввода.
Выполняет бинарный поиск в диапазоне [begin, end) и возвращает позицию первого вхождения значения value. Если такое значение не найдено, возвращает позицию, в которой оно могло-бы быть вставлено.
Элементы в диапазоне [begin, end) должны быть отсортированы по возрастанию; см. qSort().
Пример:
QList<int> list; list << 3 << 3 << 6 << 6 << 6 << 8; QList<int>::iterator i = qLowerBound(list.begin(), list.end(), 5); list.insert(i, 5); // list: [ 3, 3, 5, 6, 6, 6, 8 ] i = qLowerBound(list.begin(), list.end(), 12); list.insert(i, 12); // list: [ 3, 3, 5, 6, 6, 6, 8, 12 ]
Данная функция требует, чтобы для типа элементов (в вышеприведенном примере это int) был определен operator<().
qLowerBound() может использоваться совместно с qUpperBound() для перебора всех вхождений нужного значения:
QVector<int> vect; vect << 3 << 3 << 6 << 6 << 6 << 8; QVector<int>::iterator begin6 = qLowerBound(vect.begin(), vect.end(), 6); QVector<int>::iterator end6 = qUpperBound(begin6, vect.end(), 6); QVector<int>::iterator i = begin6; while (i != end6) { *i = 7; ++i; } // vect: [ 3, 3, 7, 7, 7, 8 ]
См. также qUpperBound() и qBinaryFind().
С помощью алгоритма сортировки кучи, сортирует по возрастанию элементы диапазона [begin, end).
Пример:
QList<int> list; list << 33 << 12 << 68 << 6 << 12; qSort(list.begin(), list.end()); // list: [ 6, 12, 12, 33, 68 ]
Алгоритм сортировки эффективен при больших наборах данных. Он выполняется за линейно-логарифмическое время, O(n log n).
Данная функция требует, чтобы для типа элементов (в вышеприведенном примере это int) был определен оператор operator<().
Если из двух элементов ни один не меньше другого, то они считаются эквивалентными, и порядок их после выполнения сортировки не определен.
См. также qStableSort() и двунаправленные итераторы.
Данная перегруженная функция-член предоставлена для удобства. Ее поведение аналогично поведению вышеприведенной функции.
Вместо оператора operator<(), для сравнения элементов, использует функцию lessThan.
Например, здесь показано, как отсортировать строки в QStringList по алфавиту без учета регистра:
bool caseInsensitiveLessThan(const QString &s1, const QString &s2) { return s1.toLower() < s2.toLower(); } int doSomething() { QStringList list; list << "AlPha" << "beTA" << "gamma" << "DELTA"; qSort(list.begin(), list.end(), caseInsensitiveLessThan); // list: [ "AlPha", "beTA", "DELTA", "gamma" ] }
Для сортировки значений в обратном порядке, в качестве параметра lessThan передайте qGreater<T>(). Например:
QList<int> list; list << 33 << 12 << 68 << 6 << 12; qSort(list.begin(), list.end(), qGreater<int>()); // list: [ 68, 33, 12, 12, 6 ]
Если из двух элементов ни один не "меньше, чем" другой, то они считаются эквивалентными. Относительный порядок таких элементов после выполнения сортировки не определен.
В качестве альтернативы к использованию qSort(), можно поместить элементы в QMap и в качестве ключа сортировки использовать ключ QMap. Зачастую, это более удобно, чем определение функции lessThan. Например, в следующем примере показано, как отсортировать список строк без учета регистра с помощью QMap:
QStringList list; list << "AlPha" << "beTA" << "gamma" << "DELTA"; QMap<QString, QString> map; foreach (QString str, list) map.insert(str.toLower(), str); list = map.values();
См. также QMap.
Данная перегруженная функция-член предоставлена для удобства. Ее поведение аналогично поведению вышеприведенной функции.
То-же самое, что и qSort(container.begin(), container.end());
Используя алгоритм сортировки кучи сортирует элементы диапазона [begin, end) в порядке возрастания.
Пример:
QList<int> list; list << 33 << 12 << 68 << 6 << 12; qStableSort(list.begin(), list.end()); // list: [ 6, 12, 12, 33, 68 ]
Алгоритм сортировки эффективен для больших наборов данных. Он выполняется за линейно-логарифмичесое время, O(n log n).
Данная функция требует, чтобы для типа элементов (в вышеприведенном примере это int) был определен operator<().
Если из двух элементов ни один не меньше другого, то они считаются эквивалентными. В этом случае, элемент, который стоял перед другим в начальном контейнере будет стоять раньше и после выполнения сортировки. Эта возможность полезна при сортировке видимых пользователем данных.
См. также qSort() и двунаправленные итераторы.
Данная перегруженная функция-член предоставлена для удобства. Ее поведение аналогично поведению вышеприведенной функции.
Для сравнения вместо оператора operator<() использует lessThan.
Например, здесь показано, как отсортировать по алфавиту без учета регистра строки в QStringList:
bool caseInsensitiveLessThan(const QString &s1, const QString &s2) { return s1.toLower() < s2.toLower(); } int doSomething() { QStringList list; list << "AlPha" << "beTA" << "gamma" << "DELTA"; qStableSort(list.begin(), list.end(), caseInsensitiveLessThan); // list: [ "AlPha", "beTA", "DELTA", "gamma" ] }
Для сортировки значений в обратном порядке, в качестве параметра lessThan передайте qGreater<T>(). Например:
QList<int> list; list << 33 << 12 << 68 << 6 << 12; qStableSort(list.begin(), list.end(), qGreater<int>()); // list: [ 68, 33, 12, 12, 6 ]
Если из двух элементов ни один не "меньше, чем" другой, то элементы считаются эквивалентными. В этом случае элемент, который стоял перед другим в начальном контейнере будет стоять раньше и после выполнения сортировки. Эта возможность полезна при сортировке видимых пользователем данных.
Данная перегруженная функция-член предоставлена для удобства. Ее поведение аналогично поведению вышеприведенной функции.
То-же самое, что и qStableSort(container.begin(), container.end());
Меняет местами значения переменных var1 и var2.
Пример:
double pi = 3.14; double e = 2.71; qSwap(pi, e); // pi == 2.71, e == 3.14
Выполняет бинарный поиск в диапазоне [begin, end) и возвращает позицию последнего вхождения значения value. Если такое значение не найдено, то возвращает позицию, в которую значение могло-бы быть вставлено.
Элементы в диапазоне [begin, end) должны быть отсортированы по возрастанию; см. qSort().
Пример:
QList<int> list; list << 3 << 3 << 6 << 6 << 6 << 8; QList<int>::iterator i = qUpperBound(list.begin(), list.end(), 5); list.insert(i, 5); // list: [ 3, 3, 5, 6, 6, 6, 8 ] i = qUpperBound(list.begin(), list.end(), 12); list.insert(i, 12); // list: [ 3, 3, 5, 6, 6, 6, 8, 12 ]
Данная функция требует, чтобы для типа значений (в вышеприведенном примере это int) был определен operator<().
qUpperBound() может использоваться совместно с qLowerBound() для перебора всех вхождений нужного значения:
QVector<int> vect; vect << 3 << 3 << 6 << 6 << 6 << 8; QVector<int>::iterator begin6 = qLowerBound(vect.begin(), vect.end(), 6); QVector<int>::iterator end6 = qUpperBound(vect.begin(), vect.end(), 6); QVector<int>::iterator i = begin6; while (i != end6) { *i = 7; ++i; } // vect: [ 3, 3, 7, 7, 7, 8 ]
См. также qLowerBound() и qBinaryFind().
Copyright © 2005 Trolltech | Trademarks | Qt 4.1.0 |