.Net C#String.GetHashCode()替代方案

时间:2014-01-21 17:20:44

标签: c# .net hash-code-uniqueness

我比较很多字符串数据(csv文件)时遇到问题。这些文件具有uniqueID但未排序且非常大。

所以我尝试创建两个字典,其中key是来自file的uniqueID,而Value是int,它返回我感兴趣的字符串的GetHashCode()以进行更改。

但是,简短的例子:

if ("30000100153:135933:Wuchterlova:335:2:Praha:16000".GetHashCode() == 
    "30000263338:158364:Radošovická:1323:10:Praha:10000".GetHashCode())
{
    Console.WriteLine("Hmm that's strange");
}

还有其他方法可以做到这一点。

我需要尽可能少的footprit(由于两个csv文件的两个字典的内存分配,其中包含大约3M行) 谢谢

2 个答案:

答案 0 :(得分:18)

首先,string.GetHashCode 的文档表示不要将字符串哈希码用于任何需要随时间稳定的应用程序,因为它们不是。您应该仅将字符串哈希码用于一个目的,即将字符串放入字典中。

其次,哈希码不是唯一的。只有40亿个可能的哈希码(因为哈希码是32位整数)但显然有超过40亿个字符串,因此必须有许多具有相同哈希码的字符串。只有几千个字符串的集合具有包含具有相同哈希码的两个字符串的极高概率。概率图如下:

http://blogs.msdn.com/b/ericlippert/archive/2010/03/22/socks-birthdays-and-hash-collisions.aspx

因此,您可能想知道字典是如何工作的,如果它使用的是GetHashCode,但可能存在冲突。答案是:当你把两个东西X和Y放在一个具有相同哈希码的字典中时,它们会进入同一个“桶”。当您搜索X时,字典会使用哈希代码转到右侧存储桶,然后对存储桶中的每个元素执行昂贵的相等检查,直到找到正确的字符。由于每个桶都很小,因此大多数时候这种检查仍然足够快。

我不知道如何解决您的问题,但使用32位哈希显然不是正确的方法,所以尝试别的。我的建议是,如果要管理大量数据,请开始使用数据库而不是CSV文件。这就是数据库的用途。

我写了许多关于字符串哈希的文章,你可能会感兴趣:

http://ericlippert.com/2011/02/28/guidelines-and-rules-for-gethashcode/

http://blogs.msdn.com/b/ericlippert/archive/2011/07/12/what-curious-property-does-this-string-have.aspx

http://blogs.msdn.com/b/ericlippert/archive/2005/10/24/do-not-use-string-hashes-for-security-purposes.aspx

http://blogs.msdn.com/b/ericlippert/archive/tags/hashing/

答案 1 :(得分:0)

您实际上并不想使用GetHashCode。你应该直接比较字符串。但是,如果不先对列表进行排序,在任何合理的时间内将每个3M字符串与另一个3M字符串进行比较将很困难。

我的方法是首先对每个列表进行排序(如何做到这取决于许多事情),读取从每个列表中排序的第一个 - 然后调用A和B,然后:

  1. 如果A = B然后做任何事情并阅读下一个A和下一个B并重复
  2. 如果A< B做任何事情并阅读下一个A并重复
  3. 如果A> B做任何事情并阅读下一个B并重复
  4. ..在那种情况下做“做什么”意味着做什么,重复意味着回到第1步。

    (这个过程是大型计算机用来合并卡片堆栈并具有特定名称的过程,但我不能为我的生活记住它!)

    干杯 -