Qt學習之路(49): 通用算法

關於Qt的model-view部分就告一段落,今天咱們開始新的部分。或許有些朋友以爲前面的部分說得很簡單。對此我也沒有辦法,畢竟,Qt是一個很龐大的庫,一時半會根本不可能窮盡全部內容,而且我也有不少東西不知道,有時候也必須去查找資料才能明白。
 
今天開始的部分是關於Qt提供的一些通用算法。這部份內容來自C++ GUI Programming with Qt 4, 2nd Edition。
 
<QtAlgorithms>提供了一系列通用的模板函數,用於實現容器上面的基本算法。這部分算法不少依賴於STL風格的遍歷器(還記得前面曾經說過的Java風格的遍歷器和STL風格的遍歷器嗎?)。實際上,C++ STL也提供了不少通用算法,包含在 <algorithm>頭文件內。這部分算法對於Qt容器一樣也是適用的。所以,若是你想使用的算法在Qt的<QtAlgorithms>頭文件中沒有包含,那麼就可使用STL的算法代替,這並不會產生什麼衝突。這裏咱們來講幾個Qt中的通用算法。雖然這些算法都是很簡單的,可是,庫函數每每會比本身編寫的更有效率,所以仍是推薦使用系統提供的函數的。
 
首先是qFind()函數。qFind()函數會在容器中查找一個特定的值。它的參數中有一個起始位置和終止位置,若是被查找的元素存在,函數返回第一個匹配項的位置,不然則返回終止位置。注意,咱們這裏說的「位置」,其實是STL風格的遍歷器。咱們知道,使用STL風格遍歷器是能夠反映一個位置的。例以下面的例子,i的值將是list.begin() + 1,而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(),所不一樣的是, qBinaryFind()是二分查找算法,它只適用於查找排序以後的集合,而qFind()則是標準的線性查找。一般,二分查找法使用條件更爲苛刻,可是效率也會更高。
 
qFill()會使用給定值對容器進行填充。例如:
 
QLinkedList< int> list(10);
qFill(list.begin(), list.end(), 1009);
 
正如其餘基於遍歷器的算法同樣,qFill()也能夠針對容器的一部分進行操做,例以下面的代碼將會把vector的前5位設置成1009,而最後5位設置爲2013:
 
QVector< int> vect(10);
qFill(vect.begin(), vect.begin() + 5, 1009);
qFill(vect.end() - 5, vect.end(), 2013);
 
qCopy()算法能夠實現將一個容器中的元素複製到另外一個容器,例如:
 
 
qCopy()也能夠用於同一容器中的元素的複製。qCopy()操做成功的關鍵是源容器和目的容器的範圍不會發生溢出。例如以下代碼,咱們將把一個列表的最後兩個元素複製給前兩個元素:
 
qCopy(list.begin(), list.begin() + 2, list.end() - 2);
 
qSort()實現了容器元素的遞增排序,使用起來也很簡單:
 
qSort(list.begin(), list.end());
 
默認狀況下,qSort()將使用 < 運算符進行元素的比較。這暗示若是須要的話,你必須定義 < 運算符。若是須要按照遞減排序,須要將qGreater<T>()看成第三個參數傳給qSort()函數。例如:
 
qSort(list.begin(), list.end(), qGreater<int>());
 
注意,這裏的T其實是容器的泛型類型。實際上,咱們能夠利用第三個參數對排序進行定義。例如,咱們自定義的數據類型中有一個大小寫不敏感的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(),所不一樣之處在於它是穩定排序。穩定排序是算法設計上的一個名詞,意思是,在排序過程當中,若是有兩個元素相等,那麼在排序結果中這兩個元素的前後順序同排序前的原始順序是一致的。舉個例子,對於一個序列:a1, a5, a32, a31, a4,它們的大小順序是a1 < a31 = a32 < a4 < a5,那麼穩定排序以後的結果應該是 a1, a32, a31, a4, a5,也就是相等的元素在排序結果中出現的順序和原始順序是一致的。穩定排序在某些場合是頗有用的,好比,如今有一份按照學號排序的學生成績單。你想按照成績高低從新進行排序,對於成績同樣的學生,仍是遵循原來的學號順序。這時候就要穩定排序了。
 
qDeleteAll()函數將對容器中存儲的全部指針進行delete操做。這個函數僅在容器元素是指針的情形下才適用。執行過這個函數以後,容器中的指針均被執行了delete運算,可是這些指針依然被存儲在容器中,成爲野指針,你須要調用容器的clear()函數來避免這些指針的誤用:
 
qDeleteAll(list);
list.clear();
 
qSwap()函數能夠交換兩個元素的位置。例如:
 
int x1 = line.x1();
int x2 = line.x2();
if (x1 > x2)
        qSwap(x1, x2);
 
最後,在<QtGlobal>頭文件中,也定義了幾個有用的函數。這個頭文件被其餘全部的頭文件include了,所以你不須要顯式的include這個頭文件了。
在這個頭文件中有這麼幾個函數:qAbs()返回參數的絕對值,qMin()和qMax()則返回兩個值的最大值和最小值。
相關文章
相關標籤/搜索