我有QMap
我希望QSet
成为它的关键,我不能这样做,因为QSet
无法比较。
例如:
QSet<int> intSet;
QMap<QSet<int>, char> charSet;
intSet.insert(1);
intSet.insert(2);
intSet.insert(3);
charSet.insert(intSet, '6');
有什么方法可以让它发挥作用吗?如果我从QSet
继承并定义operator <
我应该如何实现它?即:比较的逻辑应该是什么?
注意:我过分关注性能
答案 0 :(得分:5)
您似乎知道如何使其工作:定义一个operator<(const QSet<int>&)
函数(我不相信Qt要求您将QSet子类化以使其工作,我知道STL不会。)
显然,在无序集上实现比较器将很困难。我认为,这样做是为了让它在恒定的时间内运行是不可能的。您可以先尝试检查大小,然后将这两个内容作为列表进行排序和比较。
但广泛地说:不要这样做。这是一种虐待。当然,您可以使用某些东西来设置不是可变数据结构的密钥。集合中的整数空间是固定的还是小的(即总是在0-1024或其他范围内)?然后尝试存储在QByteArray中的位掩码。等...
答案 1 :(得分:1)
你可以制作像这样的哈希方法
uint qHash(const QSet<int>& set) {
uint seed = 0;
for(int x : set) {
seed ^= qHash(x) + 0x9e1559a9 + (seed << 6) + (seed >> 2);
}
return seed;
}
然后你的QMap就像这样
QMap<uint, char> charSet;
其中uint是先前方法的结果。
实际上这种方式不稳定100%,这取决于你的哈希函数。
答案 2 :(得分:0)
假设你并不担心性能(如果你使用容器作为关键,我认为这是一个公平的假设),那么我会做这样的事情。
QSet<int> intSet;
intSet << 1 << 2 << 3 << 3 << 4;
QVector<int> intVector;
intVector.reserve(intSet.size());
qCopy(intSet.begin(), intSet.end(), std::back_inserter(intVector)); // QVector doesn't have a std::vector range constructor atm
qSort(intVector);
QHash<QVector<int>, char> charHash;
charHash[intVector] = '6';
添加速度非常慢,但查找应该(相对)快。
我建议你想出一个更好的钥匙。也许是一个具有固定数量的int的简单类,您只需定义必要的运算符即可将其放入map / hash中。
答案 3 :(得分:0)
您似乎不需要值语义。禾为什么不用:
QHash<QSet<int> *, char> charSet;
//then to insert a set
charSet.insert(& intSet, '6');
但是对于每个集合,只有一个字符与集合对应,那么为什么不扩展QSet并添加其他成员?