1. 程式人生 > >Qt中的通用模板演算法QtAlgorithms(qDeleteAll,qBinaryFind,qCountLeadingZeroBits,qPopulationCount,qFill,qSwap,qSort)

Qt中的通用模板演算法QtAlgorithms(qDeleteAll,qBinaryFind,qCountLeadingZeroBits,qPopulationCount,qFill,qSwap,qSort)

Qt在<QtAlgorithms>標頭檔案中為我們提供了一系列的全域性模板方法,這些模板方法主要用於容器操作,比如qDeleteAll()。其在Qt中的宣告如下:


void qDeleteAll(ForwardIterator begin, ForwardIterator end)
void qDeleteAll(const Container &c)
        該方法接受一個容器或由兩個迭代器確定的容器區間,其作用是對容器中的每一個元素呼叫operator delete釋放元素所佔用的空間。所以,作為引數傳遞的容器中的元素必須是non-const 指標型別,不能是基本資料型別。同時,這些演算法能用於任何具有STL風格迭代器的容器,包括QList,QLinkedList,QVector, QMap,QHash等。注意,qDeleteAll() 只是釋放容器中每個指標元素所佔用的空間,並不會清空容器或容器區間。比如,


QList<Employee *> list;
list.append(new Employee("Blackpool", "Stephen"));
list.append(new Employee("Twist", "Oliver"));

qDeleteAll(list.begin(), list.end());
list.clear();
像上面的例子所示,如果我們想清空容器,必須手動呼叫一下容器的相關成員函式。另一方面,當qDeleteAll() 應用於關聯容器時,如QMap,QHash等,這些容器中往往存放的都是key-value對,但qDeleteAll() 只能釋放value所對應的記憶體空間,而不能釋放key所對應的記憶體空間。
        大部分方法都和上面一樣接受STL風格的迭代器作為引數,並且由於這些方法是通用方法,不依賴具體的迭代器類,所以可以將任何滿足條件的迭代器作為引數傳入。當然,迭代器的型別要和方法的需求一致,比如qFill() 方法接受兩個forward iterator,就必須傳遞兩個前向迭代器進去,否則會引發編譯錯誤。並且我們知道在STL中,任何行為像迭代器的東西就是迭代器。對於Qt來說也是一樣,所以,這些方法不僅僅能應用於標準的Qt容器和STL容器,也可以應用於普通的陣列和指標。比如,下面的例子,對於name_table陣列中的每一個HTML實體,在value_table中查詢該實體所對應的Unicode編碼。因為name_table 是按字母排序的,所以此處可以使用qBinaryFind() 進行二分查詢。


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]);
}
 Qt容器所支援的迭代器型別 

       上面說到這些通用演算法主要用於操作容器,而操作容器最常用的方式就是使用迭代器,所以,我們在看一下Qt中所支援的迭代器型別:

       輸入迭代器

       輸入迭代器可以用來從一個容器中順序的讀取資料。所以這種迭代器必須提供==和!=運算子來比較兩個迭代器是否相等,同時還得有取得每項資料的*運算子和迭代到下一項的++運算子。Qt中容器的迭代器型別都是輸入迭代器。

        輸出迭代器

        輸出迭代器用來想容器中順序的寫入資料。其操作和上面的輸入迭代器大同小異。其也提供了用於存取資料的*運算子和迭代到下一項的++運算子。Qt容器的non-const 迭代器都是輸入迭代器。

        前向迭代器

        前向迭代器其實就是 既滿足輸入迭代器的要求又滿足輸出迭代器的要求的一種迭代器。Qt容器的所有non-const容器都是前向迭代器。

        雙向迭代器

        雙向迭代器除了滿足前向迭代器的要求外,還提供了--運算子以實現向後迭代的功能。Qt容器的non-const迭代器都是雙向迭代器。

        隨機存取迭代器

        隨機存取迭代器是最後一種,也是功能最強大的一種迭代器,它不僅支援雙向迭代器的操作,還支援以下各種操作:

         
i += n 將迭代器想前步進n位
i -= n 將迭代器向後步進n位
i +n or n + i 返回迭代器i前面n位所對應的迭代器
i - n 返回迭代器i後面n位所對應的迭代器
i - j 返回迭代器i 和 j 之間的元素的個數
i[n] 等價於 *(i + n)
i < j  比較迭代器i是否在迭代器j的後面

Qt中的QList 和 QVector 的non-const 迭代器是隨機存取迭代器。
其他通用方法

        除了上面的qDeleteAll() 演算法,Qt在<QtAlgorithms>標頭檔案裡還為我們提供了另外兩個通用方法,宣告如下:


uint qCountLeadingZeroBits(quint32 v)
uint qCountLeadingZeroBits(quint8 v)
uint qCountLeadingZeroBits(quint16 v)
uint qCountLeadingZeroBits(quint64 v)
uint qCountTrailingZeroBits(quint32 v)
uint qCountTrailingZeroBits(quint8 v)
uint qCountTrailingZeroBits(quint16 v)
uint qCountTrailingZeroBits(quint64 v)
uint qPopulationCount(quint32 v)
uint qPopulationCount(quint8 v)
uint qPopulationCount(quint16 v)
uint qPopulationCount(quint64 v)
qCountLeadingZeroBits() 用於計算一個整數所對應的二進位制數中從最高位(MSB)算起有多少個0,比如 qCountLeadingZeroBits(8) 返回28,因為十進位制 “8” 所對應的二進位制是“1000”,總共32位,所以從最高位算起有28個0。

qCountTrailingZeroBits() 的作用同上,只不過其返回的是從最低有效位(LSB)算起有多少個0。

qPopulationCount() 返回一個整數的二進位制表示中 1 的個數。該個數稱為 數字的 “漢明權重”。關於“漢明權重”的詳細資訊可參看維基百科漢明權重。

被廢棄的通用方法

        除了上面說的三個通用方法,其實Qt還提供了其他的通用方法,比如上面提到過的qBinaryFind()。但由於這些通用方法大多和STL中的標準演算法功能重複,所以,從Qt5.0開始,這些就被標記為廢棄的函式,而建議大家直接使用STL中的標準演算法。Qt5.7中所列的被廢棄的演算法如下:


RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
Container::const_iterator qBinaryFind(const Container &container, const T &value)
OutputIterator qCopy(InputIterator begin1, InputIterator end1, OutputIterator begin2)
BiIterator2 qCopyBackward(BiIterator1 begin1, BiIterator1 end1, BiIterator2 end2)
void qCount(InputIterator begin, InputIterator end, const T &value, Size &n)
void qCount(const Container &container, const T &value, Size &n)
bool qEqual(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2)
void qFill(ForwardIterator begin, ForwardIterator end, const T &value)
void qFill(Container &container, const T &value)
InputIterator qFind(InputIterator begin, InputIterator end, const T &value)
Container::const_iterator qFind(const Container &container, const T &value)
LessThan qGreater()
LessThan qLess()
RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
Container::const_iterator qLowerBound(const Container &container, const T &value)
void qSort(RandomAccessIterator begin, RandomAccessIterator end)
void qSort(RandomAccessIterator begin, RandomAccessIterator end, LessThan lessThan)
void qSort(Container &container)
void qStableSort(RandomAccessIterator begin, RandomAccessIterator end)
void qStableSort(RandomAccessIterator begin, RandomAccessIterator end, LessThan lessThan)
void qStableSort(Container &container)
void qSwap(T &var1, T &var2)
RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
Container::const_iterator qUpperBound(const Container &container, const T &value)

這些函式大都可以見名知意,在此就不詳細講解了。另外,這些函式被標記為廢棄,但並未從qt中移除,所以關於每個函式的具體資訊,可參看Qt幫助文件。但還是建議不要使用這些被廢棄的函式,以免這些函式在將來的某個版本被移除而導致程式碼的不可移植性。
---------------------
作者:求道玉
來源:CSDN
原文:https://blog.csdn.net/Amnes1a/article/details/60868344
版權宣告:本文為博主原創文章,轉載請附上博文連結!