欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++?Qt開發(fā)之關(guān)聯(lián)容器類使用方法詳解

 更新時間:2023年12月11日 09:47:32   作者:微軟技術(shù)分享  
當(dāng)我們談?wù)摼幊讨械臄?shù)據(jù)結(jié)構(gòu)時,順序容器是不可忽視的一個重要概念,Qt?中提供了豐富的容器類,用于方便地管理和操作數(shù)據(jù),本章我們將主要學(xué)習(xí)關(guān)聯(lián)容器,主要包括?QMap?,QSet和?QHash,感興趣的朋友跟著小編一起來學(xué)習(xí)吧

引言

當(dāng)我們談?wù)摼幊讨械臄?shù)據(jù)結(jié)構(gòu)時,順序容器是不可忽視的一個重要概念。順序容器是一種能夠按照元素添加的順序來存儲和檢索數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)。它們提供了簡單而直觀的方式來組織和管理數(shù)據(jù),為程序員提供了靈活性和性能的平衡。

Qt 中提供了豐富的容器類,用于方便地管理和操作數(shù)據(jù)。這些容器類涵蓋了各種不同的用途,從簡單的動態(tài)數(shù)組到復(fù)雜的映射和集合。本章我們將主要學(xué)習(xí)關(guān)聯(lián)容器,主要包括 QMap ,QSet和 QHash,它們提供了鍵值對存儲和檢索的功能,允許通過鍵來快速查找值。

1. QMap

QMap 是 Qt 中的有序關(guān)聯(lián)容器,用于存儲鍵值對,并按鍵的升序進(jìn)行排序。以下是關(guān)于 QMap 的概述:

1.1 特點和用途

  • 有序性: QMap 中的元素是有序的,按照鍵的升序進(jìn)行排列。
  • 唯一鍵: 每個鍵在 QMap 中是唯一的,不允許重復(fù)鍵。
  • 鍵值對存儲: 存儲鍵值對,每個鍵關(guān)聯(lián)一個值。
  • 性能: 插入和查找操作的平均復(fù)雜度是 O(log n),適用于需要按鍵排序并進(jìn)行頻繁查找的場景。

1.2 函數(shù)和功能

以下是關(guān)于 QMap 常用函數(shù)及其功能的總結(jié):

函數(shù)功能
insert(const Key &key, const T &value)向 QMap 中插入鍵值對。
insertMulti(const Key &key, const T &value)向 QMap 中插入允許相同鍵的多個值。
remove(const Key &key)移除指定鍵的元素。
value(const Key &key) const返回指定鍵的值。
contains(const Key &key) const判斷是否包含指定鍵。
isEmpty() const判斷 QMap 是否為空。
size() const返回 QMap 中鍵值對的數(shù)量。
clear()清空 QMap 中的所有元素。
keys() const返回 QMap 中所有鍵的列表。
values() const返回 QMap 中所有值的列表。
begin()返回指向 QMap 開始位置的迭代器。
end()返回指向 QMap 結(jié)束位置的迭代器。
constBegin() const返回指向 QMap 開始位置的常量迭代器。
constEnd() const返回指向 QMap 結(jié)束位置的常量迭代器。
find(const Key &key) const返回指向 QMap 中指定鍵的迭代器。
lowerBound(const Key &key) const返回指向 QMap 中不小于指定鍵的第一個元素的迭代器。
upperBound(const Key &key) const返回指向 QMap 中大于指定鍵的第一個元素的迭代器。
count(const Key &key) const返回指定鍵的數(shù)量。
toStdMap() const將 QMap 轉(zhuǎn)換為 std::map。

這些函數(shù)提供了對 QMap 中鍵值對的插入、刪除、查找和遍歷等操作。根據(jù)需求選擇適當(dāng)?shù)暮瘮?shù)以滿足操作要求。

1.3 應(yīng)用案例

正如如下代碼所示,我們提供了QMap<QString,QString>字典類型的關(guān)聯(lián)數(shù)組,該數(shù)組中一個鍵映射對應(yīng)一個值,QMap容器是按照順序存儲的,如果項目中不在意順序可以使用QHash容器,使用QHash效率更高些。

#include <QCoreApplication>
#include <iostream>
#include <QString>
#include <QtGlobal>
#include <QMap>
#include <QMapIterator>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QMap<QString,QString> map;

    map["1001"] = "admin";
    map["1002"] = "guest";
    map.insert("1003","lyshark");
    map.insert("1004","lucy");
    // map.remove("1002");

    // 根據(jù)鍵值對查詢屬性
    std::cout << map["1002"].toStdString().data() << std::endl;
    std::cout << map.value("1003").toStdString().data() << std::endl;
    std::cout << map.key("admin").toStdString().data() << std::endl;

    // 使用STL語法迭代枚舉Map鍵值對
    QMap<QString,QString>::const_iterator x;
    for(x=map.constBegin();x != map.constEnd(); ++x)
    {
        std::cout << x.key().toStdString().data() << " : ";
        std::cout << x.value().toStdString().data() << std::endl;
    }

    // 使用STL語法實現(xiàn)修改鍵值對
    QMap<QString,QString>::iterator write_x;
    write_x = map.find("1003");
    if(write_x !=map.end())
        write_x.value()= "you ary in";

    // 使用QTglobal中自帶的foreach遍歷鍵值對
    QString each;

    // --> 單循環(huán)遍歷
    foreach(const QString &each,map.keys())
    {
        std::cout << map.value(each).toStdString().data() << std::endl;
    }

    // --> 多循環(huán)遍歷
    foreach(const QString &each,map.uniqueKeys())
    {
        foreach(QString x,map.value(each))
        {
            std::cout << each.toStdString().data() << " : ";
            std::cout << x.toStdString().data() << std::endl;
        }
    }

    return a.exec();
}

上述代碼是如何使用QMap容器,其實還有一個QMultiMap容器,該容器其實是QMap的一個子集,用于處理多值映射的類,也就是說傳統(tǒng)QMap只能是一對一的關(guān)系,而QMultiMap則可以實現(xiàn)一個Key對應(yīng)多個Value或者是反過來亦可,實現(xiàn)一對多的關(guān)系。

如果總結(jié)起來可以發(fā)現(xiàn)兩者的異同點;

QMap

  • 唯一鍵: QMap 中每個鍵都是唯一的,不允許重復(fù)鍵。
  • 鍵排序: QMap 中的元素是按鍵的升序排列的。
  • 使用場景: 適用于需要鍵值對有序且鍵唯一的場景。

QMultiMap

  • 允許重復(fù)鍵: QMultiMap 中可以包含重復(fù)的鍵,即多個鍵可以映射到相同的值。
  • 鍵排序: QMultiMap 中的元素是按鍵的升序排列的。
  • 使用場景: 適用于允許鍵重復(fù),并且需要鍵值對有序的場景。

相同點

  • 鍵值對: 都是用于存儲鍵值對的容器。
  • 有序性: 元素在容器中是有序的,按鍵的升序排列。

不同點

  • 鍵唯一性: QMap 中每個鍵都是唯一的,而 QMultiMap 允許重復(fù)的鍵。
  • 使用場景: QMap 適用于需要鍵唯一的情況,而 QMultiMap 適用于允許鍵重復(fù)的情況。

如下所示,展示了如何使用QMultiMap實現(xiàn)一對多的映射關(guān)系;

#include <QCoreApplication>
#include <iostream>
#include <QString>
#include <QList>
#include <QMultiMap>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QMultiMap<QString,QString> mapA,mapB,mapC,mapD;

    mapA.insert("lyshark","1000");
    mapA.insert("lyshark","2000");
    mapB.insert("admin","3000");
    mapB.insert("admin","4000");
    mapC.insert("admin","5000");

    // 獲取到里面的所有key=lyshark的值
    QList<QString> ref;

    ref = mapA.values("lyshark");
    for(int x=0;x<ref.size();++x)
    {
        std::cout << ref.at(x).toStdString().data() << std::endl;
    }

    // 兩個key相同可相加后輸出
    mapD = mapB + mapC;

    ref = mapD.values("admin");
    for(int x=0;x<ref.size();x++)
    {
        std::cout << ref.at(x).toStdString().data() << std::endl;
    }

    return a.exec();
}

2. QHash

QHash 是一個無序的關(guān)聯(lián)容器,它存儲鍵值對,但與 QMap 不同,QHash 不會對鍵進(jìn)行排序。

2.1 特點和用途

  • 鍵值對存儲: QHash 中的元素以鍵值對的形式存儲,但與 QMap 不同,QHash 中的元素是無序的。

  • 無序性: QHash 中的元素是無序的,沒有特定的排列順序。

  • 唯一鍵: 每個鍵在 QHash 中是唯一的,不允許重復(fù)鍵。

  • 性能: 插入和查找操作的平均復(fù)雜度是 O(1),適用于需要快速插入和查找的場景。

2.2 函數(shù)和功能

以下是關(guān)于 QHash 常用函數(shù)及其功能的總結(jié):

函數(shù)功能
insert(const Key &key, const T &value)向 QHash 中插入鍵值對。
insertMulti(const Key &key, const T &value)向 QHash 中插入允許相同鍵的多個值。
remove(const Key &key)移除指定鍵的元素。
value(const Key &key) const返回指定鍵的值。
contains(const Key &key) const判斷是否包含指定鍵。
isEmpty() const判斷 QHash 是否為空。
size() const返回 QHash 中鍵值對的數(shù)量。
clear()清空 QHash 中的所有元素。
keys() const返回 QHash 中所有鍵的列表。
values() const返回 QHash 中所有值的列表。
begin()返回指向 QHash 開始位置的迭代器。
end()返回指向 QHash 結(jié)束位置的迭代器。
constBegin() const返回指向 QHash 開始位置的常量迭代器。
constEnd() const返回指向 QHash 結(jié)束位置的常量迭代器。
find(const Key &key) const返回指向 QHash 中指定鍵的迭代器。
count(const Key &key) const返回指定鍵的數(shù)量。
unite(const QHash &other)合并兩個 QHash,將 other 中的元素合并到當(dāng)前 QHash
intersect(const QHash &other)保留兩個 QHash 中共有的元素,刪除其他元素。
subtract(const QHash &other)從當(dāng)前 QHash 中移除與 other 共有的元素。
toStdHash() const將 QHash 轉(zhuǎn)換為 std::unordered_map。

這些函數(shù)提供了對 QHash 中鍵值對的插入、刪除、查找和遍歷等操作。根據(jù)需求選擇適當(dāng)?shù)暮瘮?shù)以滿足操作要求。

2.3 應(yīng)用案例

QHashQMap其實是一樣的,如果不需要對鍵值對進(jìn)行排序那么使用QHash將會得到更高的效率,正是因為Hash的無序,才讓其具備了更加高效的處理能力。

#include <QCoreApplication>
#include <iostream>
#include <QString>
#include <QHash>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QHash<QString, QString> hash;

    hash["1001"] = "admin";
    hash["1002"] = "guest";
    hash.insert("1003", "lyshark");
    hash.insert("1004", "lucy");
    // hash.remove("1002");

    // 根據(jù)鍵值對查詢屬性
    std::cout << hash["1002"].toStdString().data() << std::endl;
    std::cout << hash.value("1003").toStdString().data() << std::endl;
    std::cout << hash.key("admin").toStdString().data() << std::endl;

    // 使用STL語法迭代枚舉Hash鍵值對
    QHash<QString, QString>::const_iterator x;
    for (x = hash.constBegin(); x != hash.constEnd(); ++x)
    {
        std::cout << x.key().toStdString().data() << " : ";
        std::cout << x.value().toStdString().data() << std::endl;
    }

    // 使用STL語法實現(xiàn)修改鍵值對
    QHash<QString, QString>::iterator write_x;
    write_x = hash.find("1003");
    if (write_x != hash.end())
        write_x.value() = "you are in";

    // 使用Qt中自帶的foreach遍歷鍵值對
    QString each;

    // --> 單循環(huán)遍歷
    foreach (const QString &each, hash.keys())
    {
        std::cout << hash.value(each).toStdString().data() << std::endl;
    }

    // --> 多循環(huán)遍歷
    foreach (const QString &each, hash.uniqueKeys())
    {
        foreach (QString x, hash.values(each))
        {
            std::cout << each.toStdString().data() << " : ";
            std::cout << x.toStdString().data() << std::endl;
        }
    }

    return a.exec();
}

這里需要說明一點,與QMap一樣,QHash也能夠使用QMultiHash其操作上與QMultiMap保持一致,此處讀者可自行嘗試。

3. QSet

QSet 是 Qt 中的無序關(guān)聯(lián)容器,類似于 C++ 標(biāo)準(zhǔn)庫的 std::unordered_set。它主要用于存儲唯一值,而不關(guān)心元素的順序。以下是關(guān)于 QSet 的概述:

3.1 特點和用途

  • 無序性: QSet 中的元素是無序的,沒有特定的排列順序。
  • 唯一值: 每個值在 QSet 中是唯一的,不允許重復(fù)值。
  • 性能: 適用于需要快速查找和檢索唯一值的場景,性能比有序容器(如 QMap)更高。
  • 底層實現(xiàn): 使用哈希表實現(xiàn),因此插入和查找操作的平均復(fù)雜度是 O(1)。

3.2 函數(shù)和功能

以下是關(guān)于 QSet 常用函數(shù)及其功能的總結(jié):

函數(shù)功能
insert(const T &value)向 QSet 中插入元素。
contains(const T &value) const判斷是否包含指定元素。
remove(const T &value)移除指定元素。
isEmpty() const判斷 QSet 是否為空。
size() const返回 QSet 中元素的數(shù)量。
clear()清空 QSet 中的所有元素。
unite(const QSet &other)合并兩個 QSet,將 other 中的元素合并到當(dāng)前 QSet。
intersect(const QSet &other)保留兩個 QSet 中共有的元素,刪除其他元素。
subtract(const QSet &other)從當(dāng)前 QSet 中移除與 other 共有的元素。
begin()返回指向 QSet 開始位置的迭代器。
end()返回指向 QSet 結(jié)束位置的迭代器。
constBegin() const返回指向 QSet 開始位置的常量迭代器。
constEnd() const返回指向 QSet 結(jié)束位置的常量迭代器。

這些函數(shù)提供了對 QSet 中元素的插入、刪除、查找和遍歷等操作。QSet 是一個無序容器,用于存儲唯一的元素。根據(jù)需求選擇適當(dāng)?shù)暮瘮?shù)以滿足操作要求。

3.3 應(yīng)用案例

QSet 集合容器,是基于散列表(哈希表)的集合模板,存儲順序同樣不定,查找速度最快,其內(nèi)部使用QHash實現(xiàn)。

#include <QCoreApplication>
#include <iostream>
#include <QString>
#include <QSet>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QSet<QString> set;

    set << "dog" << "cat" << "tiger";

    // 測試某值是否包含于集合
    if(set.contains("cat"))
    {
        std::cout << "include" << std::endl;
    }

    return a.exec();
}

4. 嵌套案例總結(jié)

4.1 QList與QMap組合

代碼通過結(jié)合使用 QList 和 QMap 實現(xiàn)了數(shù)據(jù)的嵌套存儲。具體而言,通過在 QMap 中存儲鍵值對,其中鍵是時間字符串,而值是包含浮點數(shù)數(shù)據(jù)的 QList。這種結(jié)構(gòu)使得可以方便地按時間檢索相關(guān)聯(lián)的數(shù)據(jù)集。

#include <QCoreApplication>
#include <iostream>
#include <QString>
#include <QtGlobal>
#include <QList>
#include <QMap>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QMap<QString,QList<float>> map;
    QList<float> ptr;

    // 指定第一組數(shù)據(jù)
    ptr.append(10.1);
    ptr.append(12.5);
    ptr.append(22.3);
    map["10:10"] = ptr;

    // 指定第二組數(shù)據(jù)
    ptr.clear();
    ptr.append(102.2);
    ptr.append(203.2);
    ptr.append(102.1);
    map["11:20"] = ptr;

    // 輸出所有的數(shù)據(jù)
    QList<float> tmp;
    foreach(QString each,map.uniqueKeys())
    {
        tmp = map.value(each);
        std::cout << "Time: " << each.toStdString().data() << std::endl;
        for(qint32 x=0;x<tmp.count();x++)
        {
            std::cout << tmp[x]<< std::endl;
        }
    }

    return a.exec();
}

在示例中,兩組數(shù)據(jù)分別對應(yīng)不同的時間鍵,每組數(shù)據(jù)存儲在相應(yīng)的 QList 中。最后,通過迭代輸出了所有數(shù)據(jù),以時間為鍵檢索相應(yīng)的數(shù)據(jù)集,并將每個數(shù)據(jù)集中的浮點數(shù)逐個輸出。整體而言,這種數(shù)據(jù)結(jié)構(gòu)的嵌套使用有助于組織和檢索多維度的數(shù)據(jù)。

4.2 QList合并為QMap

通過使用 QList 存儲頭部信息(Header)和相應(yīng)的數(shù)值信息(Values),然后通過循環(huán)迭代將兩個列表合并為一個 QMap。在這個 QMap 中,頭部信息作為鍵,而數(shù)值作為相應(yīng)的值,形成了一個鍵值對應(yīng)的字典結(jié)構(gòu)。最后,通過 QMap 的鍵值對操作,輸出了特定字典中的數(shù)據(jù)。

#include <QCoreApplication>
#include <iostream>
#include <QString>
#include <QtGlobal>
#include <QList>
#include <QMap>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QList<QString> Header = {"MemTotal","MemFree","Cached","SwapTotal","SwapFree"};
    QList<float> Values = {12.5,46.8,68,100.3,55.9};
    QMap<QString,float> map;

    // 將列表合并為一個字典
    for(int x=0;x<Header.count();x++)
    {
        QString head = Header[x].toStdString().data();
        float val = Values[x];
        map[head] = val;
    }

    // 輸出特定字典中的數(shù)據(jù)
    std::cout << map.key(100.3).toStdString().data() << std::endl;
    std::cout << map.value("SwapTotal") << std::endl;

    return a.exec();
}

整體而言,這樣的數(shù)據(jù)結(jié)構(gòu)使得能夠更方便地按照特定的頭部信息檢索相應(yīng)的數(shù)值。

4.3 QMap拆分為QList

這段代碼演示了如何使用 QMap 存儲鍵值對,并分別將鍵和值存儲到兩個 QList 中。首先,通過 Display 函數(shù)輸出了 QMap 中的鍵值對。

接著,通過 map.keys() 和 map.values() 分別獲取 QMap 中的所有鍵和值,將它們存儲到兩個 QList 中,并使用循環(huán)分別輸出了這兩個列表的內(nèi)容。

#include <QCoreApplication>
#include <iostream>
#include <QString>
#include <QtGlobal>
#include <QList>
#include <QMap>

void Display(QMap<QString,float> map)
{
    foreach(const QString &each,map.uniqueKeys())
    {
        std::cout << each.toStdString().data() << std::endl;
        std::cout << map.value(each) << std::endl;
    }
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QMap<QString,float> map;

    map["MemTotal"] = 12.5;
    map["MemFree"] = 32.1;
    map["Cached"] = 19.2;

    Display(map);

    QList<QString> map_key;
    QList<float> map_value;

    // 分別存儲起來
    map_key = map.keys();
    map_value = map.values();

    // 輸出所有的key值
    for(int x=0;x<map_key.count();x++)
    {
        std::cout << map_key[x].toStdString().data() << std::endl;
    }

    // 輸出所有的value值
    for(int x=0;x<map_value.count();x++)
    {
        std::cout << map_value[x] << std::endl;
    }

    return a.exec();
}

4.4 QList結(jié)構(gòu)體排序

實現(xiàn)對包含結(jié)構(gòu)體 MyStruct 的 QList 進(jìn)行排序,并輸出排序后的結(jié)果。首先,定義了一個包含整數(shù)的 QList,通過 std::sort 函數(shù)按從大到小的順序?qū)υ摿斜磉M(jìn)行排序,并使用 Display 函數(shù)輸出排序后的結(jié)果。

其次,定義結(jié)構(gòu)體 MyStruct,其中包含兩個成員變量 uuid 和 uname。創(chuàng)建一個存儲該結(jié)構(gòu)體的 QList,并添加了幾個結(jié)構(gòu)體對象。通過 devListSort 函數(shù),以結(jié)構(gòu)體的 uuid 成員進(jìn)行排序,并使用循環(huán)輸出排序后的結(jié)果。

#include <QCoreApplication>
#include <iostream>
#include <QString>
#include <QtGlobal>
#include <QList>

struct MyStruct
{
    int uuid;
    QString uname;
};

void Display(QList<int> ptr)
{
    foreach(const int &each,ptr)
        std::cout << each << " ";
    std::cout << std::endl;
}

// 由大到小排列
int compare(const int &infoA,const int &infoB)
{
    return infoA > infoB;
}

// 針對結(jié)構(gòu)體的排序方法
void devListSort(QList<MyStruct> *list)
{
    std::sort(list->begin(),list->end(),[](const MyStruct &infoA,const MyStruct &infoB)
    {
        return infoA.uuid < infoB.uuid;
    });
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 定義并對單一數(shù)組排序
    QList<int> list = {56,88,34,61,79,82,34,67,88,1};
    std::sort(list.begin(),list.end(),compare);
    Display(list);

    // 定義并對結(jié)構(gòu)體排序
    QList<MyStruct> list_struct;
    MyStruct ptr;

    ptr.uuid=1005;
    ptr.uname="admin";
    list_struct.append(ptr);

    ptr.uuid=1002;
    ptr.uname = "guest";
    list_struct.append(ptr);

    ptr.uuid = 1000;
    ptr.uname = "lyshark";
    list_struct.append(ptr);

    devListSort(&list_struct);

    for(int x=0;x< list_struct.count();x++)
    {
        std::cout << list_struct[x].uuid << " ---> ";
        std::cout << list_struct[x].uname.toStdString().data() << std::endl;
    }

    return a.exec();
}

上述這段代碼演示了如何對一個包含整數(shù)的列表和一個包含結(jié)構(gòu)體的列表進(jìn)行排序,并輸出排序后的結(jié)果。在結(jié)構(gòu)體排序的情況下,使用了自定義的排序方法 devListSort,該方法按照結(jié)構(gòu)體的 uuid 成員進(jìn)行升序排序。

以上就是C++ Qt開發(fā)之關(guān)聯(lián)容器類使用方法詳解的詳細(xì)內(nèi)容,更多關(guān)于C++ Qt關(guān)聯(lián)容器類使用的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論