【Qt】之QSet使用
描述
QSet类是一个模板类,它提供基于散列表的集合。
QSet是Qt的通用容器类之一。它以未指定的顺序存储值,并提供非常快速的值查找。在内部,QSet是作为QHash实现的。
下面是一个带有QString值的QSet示例:
QSet<QString> set;
插入方式1:
set.insert("one");
set.insert("three");
set.insert("seven");
插入方式2:
set << "twelve" << "fifteen" << "nineteen";
判断是否包含:
if (!set.contains("ninety-nine"))
...
如果要浏览存储在QSet中的所有值,可以使用迭代器。QSet支持java风格的迭代器(QSetIterator和QMutableSetIterator)和stl风格的迭代器(QSet::iterator和QSet::const_iterator)。
下面是QSet使用java风格的迭代器:
QSetIterator<QWidget *> i(set);
while (i.hasNext())
qDebug() << i.next();
下面是使用STL-style
风格迭代器:
QSet<QWidget *>::const_iterator i = set.constBegin();
while (i != set.constEnd()) {
qDebug() << *i;
++i;
}
QSet是无序的,因此不能假定迭代器的序列是可预测的。如果需要按键排序,请使用QMap。
要在QSet中导航,还可以使用foreach:
QSet<QString> set;
...
foreach (const QString &value, set)
qDebug() << value;
可以使用remove()
从集合中删除项。还有一个clear()
函数可以删除所有项。
QSet
的值数据类型必须是可赋值的数据类型。例如,不能将QWidget
存储为值;相反,存储一个QWidget *
。此外,该类型必须提供operator==()
,并且还必须有一个全局qHash()
函数,该函数返回键类型参数的散列值。有关QHash()
支持的类型列表,可以参考QHash
文档。
在内部,QSet
使用散列表来执行查找。哈希表自动增长和收缩,以提供快速查找而不浪费内存。如果已经大致知道QSet
将包含多少元素,仍然可以通过调用reserve()来
控制哈希表的大小,但这不是获得良好性能所必需的。还可以调用capacity()
来检索哈希表的大小。
示例
#include <QDebug>
#include <QSet>
#include <QSetIterator>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QSet<QString> set;
// 重置大小
set.reserve(10);
// 输出容量
qDebug().noquote() << "容量 :" << set.capacity();
// 插入数据
set.insert("1");
set.insert("12");
set.insert("21");
set.insert("212");
set.insert("121");
// 输出实际大小
qDebug().noquote() << "实际大小:" << set.size();
// 输出内容
qDebug().noquote() << "输出内容 :" << set;
// 遍历
/// 1. java style
QSetIterator<QString> it_java(set);
while (it_java.hasNext()) {
qDebug().noquote() << "java_style : " << it_java.next();
}
/// 2. stl style
QSet<QString>::const_iterator it_stl = set.cbegin();
while (it_stl != set.cend()) {
qDebug().noquote() << "stl_style : " << *it_stl;
++it_stl;
}
// 是否包含
if(set.contains("121"))
qDebug().noquote() << "" << "存在";
else
qDebug().noquote() << "" << "不存在";
// 是否是空
qDebug().noquote() << "是否为空 :" << set.isEmpty();
// 移除某值
set.remove("121");
// 输出成QList
QList<QString> listStrs = set.toList();
qDebug().noquote() << "输出成QList :" << listStrs;
// 输出所有元素
qDebug().noquote() << "输出元素 :" << set.values();
// 清除
set.clear();
// 是否为空
qDebug().noquote() << "是否为空 :" << set.isEmpty();
return a.exec();
}
结果
使用场景
- 消除重复项:如果有一个包含重复项的列表或数组,并且想要消除重复项,可以使用QSet。QSet会自动删除重复的元素,只保留唯一的元素。
- 快速查找:QSet提供了高效的插入、查找和删除操作。如果需要频繁地查找元素是否存在于一个集合中,QSet是一个很好的选择。它的查找操作的时间复杂度接近于O(1),因此非常快速。
- 集合运算:QSet支持常见的集合运算,如并集、交集和差集。可以使用QSet来执行这些操作,对两个集合进行合并、比较或找出它们的共同元素。
- 存储唯一标识符:在某些情况下,可能需要存储一组唯一标识符,例如数据库中的唯一ID或网络中的唯一连接。QSet可以方便地存储这些标识符,并确保每个标识符只出现一次。
- 跟踪状态:如果需要跟踪一组对象的状态,并确保每个状态只出现一次,可以使用QSet。例如,在一个游戏中,可能需要跟踪玩家已经访问过的关卡,以确保他们不会重复访问。
结论
平平无奇
。