繁体   English   中英

在QMap或QHash中进行QSet

[英]QSet in QMap or QHash

我有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 <我应该如何实现它? 即:比较的逻辑应该是什么?

注意:我太在乎性能了

你似乎知道如何使它工作:定义一个operator<(const QSet<int>&)函数(我不相信Qt要求你将QSet子类化以使其工作,我知道STL没有)。

显然,在无序集上实现比较器将很困难。 我认为,这样做是为了让它在恒定的时间内运行是不可能的。 您可以尝试先检查大小,然后将这两个内容作为列表进行排序和比较。

但广泛地说:不要这样做。 这是一种虐待。 当然,您可以使用某些东西来设置不是可变数据结构的密钥。 集合中的整数空间是固定的还是小的(即总是在0-1024或其他范围内)? 然后尝试存储在QByteArray中的位掩码。 等等...

你可以制作这样的哈希方法

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%,这取决于你的哈希函数。

假设你并不担心性能(如果你使用容器作为关键,我认为这是一个公平的假设),那么我会做这样的事情。

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中。

看起来你不需要值语义。 禾为什么不用:

QHash<QSet<int> *, char> charSet;
//then to insert a set
charSet.insert(& intSet, '6');

但是对于每个集合,只有一个字符与集合对应,那么为什么不扩展QSet并添加其他成员?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM