作者:Never_F_Y | 来源:互联网 | 2023-05-27 13:40
在下面的代码中,我试图检查两个字符串是否是字谜.为此,我计算哈希表中两个字符串中的字符,方法是将唯一字符作为键存储,并将其作为值存储在字符串中.最后,当我去检查,如果每个角色都具有相同的数,我得到一个错误的输出中看到标示为代码"问题"就行了.但是当我将该行中的值转换为字符串时,代码工作正常.我错过了什么?
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;
}
}
}
Thomas Leves..
5
这个Hashtable
班不是通用的; 它只包含Object
s,而不是特定类型.
当你这样做:
if (uniqueChars1[key] != uniqueChars2[key])
编译时类型uniqueChars[key]
是Object
,不是Int32
.所以你正在使用Object
不等式运算符的实现,它只是比较引用.由于Int32
是一个值类型,并且索引器返回一个对象,因此该值被加框 ; 并且由于您正在装箱两个值,因此您将获得两个不同的对象实例,因此引用相等性始终返回false.
你有几个选择:
使用a Dictionary
,这是通用的等价物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关于值类型,引用类型和参数传递的精彩文章.
1> Thomas Leves..:
这个Hashtable
班不是通用的; 它只包含Object
s,而不是特定类型.
当你这样做:
if (uniqueChars1[key] != uniqueChars2[key])
编译时类型uniqueChars[key]
是Object
,不是Int32
.所以你正在使用Object
不等式运算符的实现,它只是比较引用.由于Int32
是一个值类型,并且索引器返回一个对象,因此该值被加框 ; 并且由于您正在装箱两个值,因此您将获得两个不同的对象实例,因此引用相等性始终返回false.
你有几个选择:
使用a Dictionary
,这是通用的等价物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关于值类型,引用类型和参数传递的精彩文章.