Add(a、b)および同様の関数を公開するストレージクラスを作成します。内部ストレージはHashSet<T>
、Tが適切な文字列タプルキーである場合があります。このキーと比較器で重要なのは、対称的なハッシュ関数と等式関数を使用することだけです。つまり、(a、b)は(b、a)に等しく、その結果、hash(a、b)== hash(b、a )。
前に指摘したように、多くのハッシュ関数にはこのプロパティがあります。たとえば、ハッシュ値の合計やxorなどです。xorを使用しないことを選択したのは、等しい文字列のすべてのペアがハッシュゼロを持つことを意味し、等しい文字列のペアが発生する可能性がある場合、ルックアップが非効率になる可能性があるためです。
以下の実装では、すべての文字列がnull以外であると想定していますが、エラーチェックはありません。
public class Storage
{
private HashSet<Key> set;
public Storage()
{
set = new HashSet<Key>(new Key.Comparer());
}
public void Add(string a, string b)
{
set.Add(new Key{A=a, B=b});
}
public bool Contains(string a, string b)
{
return set.Contains(new Key{A=a, B=b});
}
internal class Key
{
internal String A { get; set; }
internal String B { get; set; }
internal class Comparer : IEqualityComparer<Key>
{
public bool Equals(Key x, Key y)
{
return (x.A == y.A && x.B == y.B) || (x.A == y.B && x.B == y.A);
}
public int GetHashCode(Key k)
{
int aHash = k.A.GetHashCode();
int bHash = k.B.GetHashCode();
// Hash for (x,y) same as hash for (y,x)
if (aHash > bHash)
return bHash * 37 + aHash;
return aHash * 37 + bHash;
}
}
}
}