QT:用QSet储存自定义结构体的问题


前几天要用QSet作为储存一个自定义的结构体(就像下面这个程序一样),结果死活不成功。。。

后来还跑到论坛上问人了,丢脸丢大了。。。


事先说明:以下这个例子是错误的

  1. #include <QtCore>  
  2.   
  3. struct node  
  4. {  
  5.     int cx, cy;  
  6.     bool operator < (const node &b) const   
  7.     {  
  8.         return cx < b.cx;  
  9.     }  
  10. };  
  11.   
  12. int main(int argc, char *argv[])  
  13. {  
  14.     QCoreApplication app(argc, argv);  
  15.   
  16.     QSet<node> ss;  
  17.     QSet<node>::iterator iter;  
  18.     node temp;  
  19.     int i, j;  
  20.     for(i=0,j=100;i<101;i++,j--)  
  21.     {  
  22.         temp.cx = i;  
  23.         temp.cy = j;  
  24.         ss.insert(temp);  
  25.     }  
  26.     for(iter=ss.begin();iter!=ss.end();++iter)  
  27.         qDebug() << iter->cx << "  " << iter->cy;  
  28.   
  29.     return 0;  
  30. }  


后来经过高手提醒,再经过自己看文档,才发现QSet和STL的set是有本质区别的,虽然它们的名字很像,前者是基于哈希表的,后者是红黑树的变种。。。。


QT文档中清楚地写着:In addition, the type must provide operator==(), and there must also be a global qHash() function that returns a hash value for an argument of the key's type. 


简而言之,就是:
QSet是基于哈希算法的,这就要求自定义的结构体Type必须提供:
1. bool operator == (const Type &b) const
2. 一个全局的uint qHash(Type key)函数


废话说完了,上正确的代码:

  1. #include <QtCore>  
  2.   
  3. struct node  
  4. {  
  5.     int cx, cy;  
  6.     bool operator < (const node &b) const   
  7.     {  
  8.         return cx < b.cx;  
  9.     }  
  10.     bool operator == (const node &b) const  
  11.     {  
  12.         return (cx==b.cx && cy==b.cy);  
  13.     }  
  14. };  
  15.   
  16. uint qHash(const node key)  
  17. {  
  18.     return key.cx + key.cy;  
  19. }  
  20.   
  21. int main(int argc, char *argv[])  
  22. {  
  23.     QCoreApplication app(argc, argv);  
  24.   
  25.     QSet<node> ss;  
  26.     QSet<node>::iterator iter;  
  27.     node temp;  
  28.     int i, j;  
  29.     for(i=0,j=100;i<101;i++,j--)  
  30.     {  
  31.         temp.cx = i;  
  32.         temp.cy = j;  
  33.         ss.insert(temp);  
  34.     }  
  35.     for(iter=ss.begin();iter!=ss.end();++iter)  
  36.         qDebug() << iter->cx << "  " << iter->cy;  
  37.   
  38.     return 0;  
  39. }  
03-27
<think>好的,用户想了解QSetQt C++中的用法或文档。首先,我需要回忆一下QSet的基本信息。QSetQt提供的一个容器类,类似于STL中的std::unordered_set,用于存储唯一值,并且提供快速的查找功能。它基于哈希表实现,所以插入、删除和查找操作的平均时间复杂度是O(1)。 接下来,我应该整理QSet的主要特性和常用方法。比如,QSet中的元素是无序的,不允许重复,支持快速的插入、删除和存在性检查。常用的方法可能包括insert()、remove()、contains(),还有交集、并集等集合操作。 然后,用户可能需要示例代码来理解如何使用QSet。我需要编写一个简单的例子,展示如何创建QSet,添加元素,检查元素是否存在,删除元素,以及遍历元素。同时,要注意Qt的包含头文件和命名空间,确保代码正确。 另外,用户可能关心QSet与QMap或QList的区别,以及何时选择QSet。这部分需要简要对比,说明QSet适合需要快速查找唯一元素的场景,而QMap适合键值对,QList适合有序元素。 还要注意QSet的模板参数要求元素类型必须有qHash()函数,这点需要提及,可能给出自定义类型的使用方法,比如如何为自定义结构体提供哈希函数。 最后,引用相关的Qt文档链接,帮助用户进一步查阅官方资料。同时,根据用户提供的引用,检查是否有相关信息需要整合,但看起来引用内容中的例子是关于QLabel的,可能不直接相关,但需要确保回答中的引用标识正确,比如用户提供的引用[^1]是关于Qt编译过程的,可能与QSet无关,所以可能不需要在此处引用,但根据用户的要求,可能需要在回答末尾添加引用标识。 生成的相关问题应该围绕QSet的扩展使用、性能对比、与其他容器的区别等,确保问题能引导用户深入理解QSet。</think>### QSet用法详解 QSetQt框架提供的基于哈希表的无序集合容器,用于存储唯一值并实现$O(1)$时间复杂度查找操作。 #### 核心特性 1. **唯一性存储**:自动过滤重复元素 2. **哈希表结构**:支持快速插入/删除/查询 3. **集合运算**:提供并集($\cup$)、交集($\cap$)等操作 4. **内存优化**:元素按哈希值分组存储 #### 基本用法示例 ```cpp #include <QSet> #include <QDebug> int main() { // 创建集合 QSet<QString> fruits; // 插入元素 fruits.insert("Apple"); fruits.insert("Banana"); fruits << "Orange" << "Grape"; // 运算符重载 // 检查存在性 if(fruits.contains("Apple")) { qDebug() << "Apple exists in set"; } // 删除元素 fruits.remove("Grape"); // 遍历集合 foreach(const QString& fruit, fruits) { qDebug() << fruit; } return 0; } ``` #### 集合操作 ```cpp QSet<int> set1 = {1, 2, 3}; QSet<int> set2 = {3, 4, 5}; QSet<int> unionSet = set1 | set2; // 并集 {1,2,3,4,5} QSet<int> intersectSet = set1 & set2; // 交集 {3} ``` #### 使用注意事项 1. **元素类型要求**:必须实现`qHash()`函数和`operator==` 2. **自定义类型处理**: ```cpp struct Person { QString name; int age; bool operator==(const Person& other) const { return name == other.name && age == other.age; } }; uint qHash(const Person& p) { return qHash(p.name) ^ qHash(p.age); } ``` 3. **性能对比**: | 操作 | QSet | QList | |----------|-----------|-----------| | 插入 | $O(1)$ | $O(1)$ | | 查找 | $O(1)$ | $O(n)$ | | 删除 | $O(1)$ | $O(n)$ | #### 官方文档参考 Qt 6官方文档:https://doc.qt.io/qt-6/qset.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值