2015-01-11 67 views
3

在下面的代码中,我试图检查两个字符串是否是anagrams。为此,我通过将唯一字符存储为字符串并将其作为值存储在字符串中,计算散列表中两个字符串中的字符。最后,当我检查每个字符是否具有相同的计数时,我会得到一个错误的输出,请参阅代码中标记为“PROBLEM”的行。但是,当我将该行中的值转换为字符串时,代码工作正常。我错过了什么?即使值相同,为什么哈希表中的值比较返回false?

static bool AreAnagrams(string input1, string input2) 
    { 
     Hashtable uniqueChars1 = new Hashtable(); 
     Hashtable uniqueChars2 = new Hashtable(); 

     // Go through first string and create a hash table of characters 
     AddToHashTable(input1, ref uniqueChars1); 
     // Go through second string and create a second hash table of characters 
     AddToHashTable(input2, ref uniqueChars2); 

     // For each unique character, if the count from both hash tables are the same, they are anagrams 
     if (uniqueChars1.Keys.Count != uniqueChars2.Keys.Count) 
     { 
      return false; 
     } 
     else 
     { 
      foreach (object key in uniqueChars1.Keys) 
      { 
       if (uniqueChars1[key] != uniqueChars2[key]) // ***PROBLEM HERE*** 
       { 
        return false; 
       } 
      } 
     } 
     return true; 
    } 

    static void AddToHashTable(string input, ref Hashtable uniqueChars) 
    { 
     foreach (char c in input) 
     { 

      if (!uniqueChars.ContainsKey(c)) 
      { 
       uniqueChars.Add(c, 1); 
      } 
      else 
      { 
       int charCount = Convert.ToInt32(uniqueChars[c]); 
       charCount++; 
       uniqueChars[c] = charCount; 
      } 
     } 
    } 
+0

为什么你使用'Hashtable'而不是'Dictionary ''? –

回答

5

Hashtable类不是通用的;它只包含Object s,不是特定的类型。

当你这样做:

if (uniqueChars1[key] != uniqueChars2[key]) 

uniqueChars[key]的编译时类型为Object,不Int32。因此,您正在使用不等式运算符的Object实现,该运算符只是比较引用。由于Int32是一个值类型,并且索引器返回一个对象,因此值为boxed;并且由于你装箱了两个值,你会得到两个不同的对象实例,所以引用相等总是返回false。

您有几种选择:

  • 使用Dictionary<char, int>,这是Hashtable
  • 的一般等价物投的值int比较之前:

    if ((int)uniqueChars1[key] != (int)uniqueChars2[key]) 
    
  • 使用Equals方法比较值:

    if (!uniqueChars1[key].Equals(uniqueChars2[key])) 
    

除非您仍在使用.NET 1.x,否则我强烈建议您在任何地方都可以使用泛型集合。它们更安全,更直观,并且对价值类型具有更好的性能。


旁注(无关您的问题):你不需要通过引用传递的HashtableAddToHashTable;如果没有ref修饰符,代码将以完全相同的方式工作,因为Hashtable是引用类型,所以它始终是一个无论如何都被传递的引用。 ref修饰符只有在您将其他参数指定给uniqueChars参数时,或者您正在传递值类型并改变其状态(通常认为是不好的事情)时才有用。我建议你阅读Jon Skeet's great article about value types, reference types, and parameter passing

+1

你的意思是'Hashtable'是一个引用类型的权利?而不是'AddToHashTable'方法' – DevEstacion

+0

@DevEstacion,是的,这就是我的意思;修复它,谢谢;) –

1

你的问题来自于!=将比较两个对象上的引用相等的事实。 uniqueCharsX[key]返回一个int在对象内部装箱,而从两个哈希表中返回相同的int时,它们返回的方框不是同一个方框,因此您得到的值不正确。

要么使用强类型的Dictionary<char, int>而不是散列表或使用!uniqueChars1[key].Equals(uniqueChars2[key])而不是uniqueChars1[key] != uniqueChars2[key]这将取代int和比较价值而不是(我强烈建议您使用词典。)

相关问题