两个关键元组的列表或字典

时间:2013-03-24 19:25:13

标签: c# dictionary

我有一组双键对的字符串{(a1,b1),(a2,b2),(a3,b3),...}。在我的场景(a1,b1)==(b1,a1)中,所以a(a1,b1)或(b1,a1)组合应该只是我的一部分。

在C#应用程序中,我需要能够:

  • 添加一对新的这些(a,b)元组
  • 有效(即快速)检查一对(a1,b1)或(b1,a1)是否已经在我的表格中。

你如何使用Dictionary [Tuple [K1,K2]]或其他东西实现这样的东西?如果使用字典,有没有办法让它考虑(K1,K2)与(K2,K1)相同,所以我不必添加两种组合?或者可以添加(K1,K2)和(K2,K1)是要走的路?

感谢。

4 个答案:

答案 0 :(得分:6)

创建一个实现IEquatable的自定义类(并确保正确覆盖GetHashCode)。然后,您可以在HashSet<T>中使用它,并且可以自动使这两对成为“相等”。

答案 1 :(得分:2)

这是作业吗?这看起来像书中的问题。

  1. 定义类Key,定义相等和哈希运算符和方法。 (这意味着您应该定义方法Equals,运算符==,方法GetHashCode,以及编译器可能需要的其他方法。)
  2. 使用HashSet<Key>

答案 2 :(得分:2)

我会使用一个字典,其中键由一个函数生成,该函数接受2个字符串并生成如下的哈希:比较两个字符串,构建一个由“较小”字符串+分隔符+“较大”字符串组成的连续字符串。这种方式顺序无关紧要。也可以实现类似的“等于”运算符。

答案 3 :(得分:2)

创建一个暴露Add(a,b)和类似函数的存储类。内部存储可以是HashSet<T>,其中T是合适的字符串元组键。关键和比较器唯一重要的是使用对称的哈希和相等函数,即(a,b)等于(b,a),因此哈希(a,b)==哈希(b,a) )。

如前所述,许多散列函数都具有此属性,例如散列值的sum和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;
          }
       }
   }

}