3

私は持っていて、その鍵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 <どのように実装すればよいですか?すなわち:比較の論理はどうあるべきですか?

注:パフォーマンスが気になりすぎます

4

4 に答える 4

5

あなたはそれを機能させる方法を知っているようです:operator<(const QSet<int>&)関数を定義します(Qtがこれを機能させるためにQSetをサブクラス化することを要求するとは思わない、私はSTLがそうではないことを知っています)。

明らかに、順序付けされていないセットにコンパレータを実装することは困難になります。そして、それが一定時間で実行されるようにすることは、不可能だと私は信じています。最初にサイズを確認してから、2つのコンテンツをリストとして並べ替えて比較するなどの方法を試してみてください。

しかし、大まかに言うと、これを行わないでください。それは虐待です。確かに、変更可能なデータ構造ではない、セットのキーに使用できるものがあります。セット内の整数のスペースは固定されていて小さいですか(つまり、常に0〜1024の範囲かどうか)?次に、QByteArrayに格納されているビットマスクを試してください。等...

于 2012-04-19T21:10:50.697 に答える
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% 安定していません。ハッシュ関数に依存します。

于 2012-04-19T21:46:24.783 に答える
0

値のセマンティクスは必要ないようです。使用しない理由:

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

ただし、各セットには、セットに対応する文字が 1 つしかないため、QSet を拡張してメンバーを追加してみませんか?

于 2012-04-19T21:39:56.580 に答える
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を持つ単純なクラスです。

于 2012-04-19T21:21:55.640 に答える