在<QtAlgorithm>頭文件中,Qt提供了一些全局的模板函數,這些函數是可以使用在容器上的十分常用的算法。我們可以在任何提供了STL風格迭代器的容器類上用這些算法,包括QList、QLinkedList、QVector、QMap和QHash。如果在目標平台上可以使用STL,那么可以使用STL的算法來代替Qt的這些算法,因為STL提供了更多的算法,而Qt只提供了其中最重要的一些算法。
在歷史上,Qt曾經提供的函數是許多STL算法函數的直接等價物。從Qt 5.0開始,QT鼓勵我們直接使用STL中可用的實現;大多數Qt已經被棄用(盡管它們仍然可以用於保持舊的代碼編譯,但會有警告)。
大多數情況下,使用廢棄的Qt算法函數的應用程序可以很容易地移植到使用等效的STL函數。你需要
添加#include <algorithm> 頭文件,並將Qt函數替換為STL對應函數,如下表所示。
Qt function | STL function |
---|---|
qBinaryFind | std::binary_search | std::lower_bound |
qCopy | std::copy |
qCopyBackward | std::copy_backward |
qEqual | std::equal |
qFill | std::fill |
qFind | std::find |
qCount | std::count |
qSort | std::sort |
qStableSort | std::stable_sort |
qLowerBound | std::lower_bound |
qUpperBound | std::upper_bound |
qLess | std::less |
qGreater | std::greater |
下面對其中幾個常用的算法進行演示,可以在幫助索引中査看Generic Algorithms關鍵字來了解其他的算法。
(1)排序
排序算法的示例如下:
//使用快速排序算法對list進行升序排序,排序后兩個12的位置不確定
QList<int> list1;
list1 << 33 << 12 << 68 << 6 << 12;
std::sort(list1.begin(), list1.end());
qDebug() << list1; // 輸出:(6, 12, 12, 33, 68)
//使用一種穩定排序算法對list2進行升序排序,排序前在前面的12,排序后依然在前面
QList<int> list2;
list2 << 33 << 12 << 68 << 6 << 12;
std::stable_sort(list2.begin(), list2.end());
qDebug() << list2; // 輸出:(6, 12, 12, 33, 68)
//使用qSort()函數和std::greater算法中使list3反向排序
QList<int> list3;
list3 << 33 << 12 << 68 << 6 << 12;
qSort(list3.begin(), list3.end(), std::greater<int>()); //Qt5已棄用
qDebug() << list3; // 輸出:(68, 33, 12, 12, 6)
默認情況下,qSort()將使用 < 運算符進行元素的比較,即升序。如果需要改為降序,需要將qGreater<T>()當作第三個參數傳給qSort()函數。
(2)查找
查找算法的示例如下:
//使用std::find()從list中查找"two",返回第一個對應的值的迭代器,如果沒有找到則返回end()
QStringList list1;
list1 << "one" << "two" << "three";
QList<QString>::iterator i = std::find(list1.begin(), list1.end(), "two");
qDebug() << *i; //輸出:"two"
//使用qFind()從list中查找"two",返回第一個對應的值的迭代器,如果沒有找到則返回end()
QStringList list2;
list2 << "one" << "two" << "three";
QStringList::iterator j = qFind(list2.begin(), list2.end(), "two");
qDebug() << *j; //輸出:"two"
另外還有個 qBinaryFind() 函數,其行為很像qFind(),所不同的是,qBinaryFind()是二分查找算法,它只適用於查找排序之后的集合,而qFind()則是標准的線性查找。通常,二分查找法使用條件更為苛刻,但是效率也會更高。
(3)復制
復制算法的示例如下:
//將list1中所有項目復制到vect1中
QStringList list1;
list1 << "one" << "two" << "three";
QVector<QString> vect1(list1.count());
std::copy(list1.begin(), list1.end(), vect1.begin());
qDebug() << vect1; //輸出:QVector("one", "two", "three")
//將list2中所有項目復制到vect2中
QStringList list2;
list2 << "one" << "two" << "three";
QVector<QString> vect2(list2.count());
qCopy(list2.begin(), list2.end(), vect2.begin());
qDebug() << vect2; //輸出:QVector("one", "two", "three")
參考: