为什么即使值相同,哈希表中的值比较也返回false? [英] Why is value comparison in hashtable returning false even when the values are the same?
问题描述
在下面的代码中,我试图检查两个字符串是否是字谜.为此,我通过将唯一字符存储为键并将其在字符串中的计数存储为值来对哈希表中两个字符串中的字符进行计数.最后,当我检查每个字符是否具有相同的计数时,我得到了错误的输出,请参见代码中标记为"PROBLEM"的行.但是,当我将该行中的值转换为字符串时,代码可以正常工作.我想念什么?
In the following code, I am trying to check if two strings are anagrams. To that, I am counting the characters in the two strings in a hash table by storing the unique characters as key and its count in the string as values. At the end, when I go to check if each of the character have the same count, I get a false output, see the line marked as "PROBLEM" in the code. But when I convert the values in that line to string, the code works fine. What am I missing?
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;
}
}
}
推荐答案
Hashtable
类不是通用类;它只包含Object
,而不是特定类型.
The Hashtable
class is not generic; it just contains Object
s, not a specific type.
执行此操作时:
if (uniqueChars1[key] != uniqueChars2[key])
uniqueChars[key]
的编译时类型为Object
,而不是Int32
.因此,您正在使用inequality运算符的Object
实现,该实现只是比较引用.由于Int32
是值类型,并且索引器返回一个对象,因此该值是盒装;并且由于要装箱两个值,所以得到两个不同的对象实例,因此引用相等始终返回false.
the compile-time type of uniqueChars[key]
is Object
, not Int32
. So you're using the Object
implementation of the inequality operator, which just compares references. Since Int32
is a value type, and the indexer returns an object, the value is boxed; and since you're boxing two values, you get two distinct object instances, so reference equality always returns false.
您有几种选择:
- 使用
Dictionary<char, int>
,与Hashtable
等效
-
在比较之前将值广播到
int
:
- use a
Dictionary<char, int>
, which is the generic equivalent ofHashtable
cast the values to
int
before comparison:
if ((int)uniqueChars1[key] != (int)uniqueChars2[key])
使用Equals
方法比较值:
use the Equals
method to compare values:
if (!uniqueChars1[key].Equals(uniqueChars2[key]))
除非您仍在使用.NET 1.x,否则我强烈建议您在所有可能的地方使用通用集合.它们更安全,更直观,并且对于值类型具有更好的性能.
Unless you're still using .NET 1.x, I strongly advise you to use generic collections everywhere you can. They're safer, more intuitive, and have better performance for value types.
旁注(与您的问题无关):您无需通过引用Hashtable
传递Hashtable
;如果没有ref
修饰符,代码将以完全相同的方式工作,因为Hashtable
是引用类型,因此无论如何它始终是传递的引用. ref
修饰符仅在为uniqueChars
参数分配其他内容时,或者在传递值类型并改变其状态(通常认为是不好的事情)时才有用.我建议您阅读乔恩·斯基特(Jon Skeet)关于值类型,引用类型和参数传递的精彩文章.
Side note (unrelated to your problem): you don't need to pass the Hashtable
by reference to AddToHashTable
; the code would work exactly the same way without the ref
modifier, because Hashtable
is a reference type, so it's always a reference that is passed anyway. The ref
modifier would only be useful if you were assigning something else to the uniqueChars
parameter, or if you were passing a value type and mutating its state (which is usually consider a bad thing). I suggest you read Jon Skeet's great article about value types, reference types, and parameter passing.
这篇关于为什么即使值相同,哈希表中的值比较也返回false?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!