在下面的代码中,我试图检查两个字符串是否是字谜。为此,我计算哈希表中两个字符串中的字符,方法是将唯一字符作为键存储,并将其作为值存储在字符串中。最后,当我去检查每个字符是否具有相同的计数时,我得到一个错误的输出,看到代码中标记为“问题”的行。但是当我将该行中的值转换为字符串时,代码工作正常。我错过了什么?
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 :(得分:5)
Hashtable
类不是通用的;它只包含Object
个,而不是特定类型。
执行此操作时:
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,否则我强烈建议您尽可能使用通用集合。它们更安全,更直观,并且在价值类型方面具有更好的性能。
旁注(与您的问题无关):您不需要通过引用传递Hashtable
AddToHashTable
;如果没有ref
修饰符,代码将以完全相同的方式工作,因为Hashtable
是引用类型,所以它始终是一个传递的引用。 ref
修饰符仅在您为uniqueChars
参数指定其他内容时,或者如果您传递值类型并改变其状态(通常认为这是一件坏事)时才有用。我建议你阅读Jon Skeet's great article about value types, reference types, and parameter passing。
答案 1 :(得分:1)
您的问题来自!=
将比较两个对象上的引用相等性这一事实。 uniqueCharsX[key]
在对象内部返回一个int框,同时从两个哈希表中返回相同的int,它们返回的框不是同一个框,因此得到的值不正确。
要么使用强类型Dictionary<char, int>
而不是哈希表,要么使用!uniqueChars1[key].Equals(uniqueChars2[key])
而不是uniqueChars1[key] != uniqueChars2[key]
,这将取消对int进行解包并在值上进行比较(我强烈建议您使用词典。)