3

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

所以我尝试创建两个字典,其中键是文件中的 uniqueID,值是 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");
}

那么有没有其他方法可以做到这一点。

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

4

2 回答 2

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-c​​urious-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/

于 2014-01-21T17:31:04.957 回答
0

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

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

  1. 如果 A = B 然后做任何事情并阅读下一个 A 和下一个 B 并重复
  2. 如果 A < B 做任何事情并阅读下一个 A 并重复
  3. 如果 A > B 做任何事情并阅读下一个 B 并重复

..其中“做任何事情”意味着在这种情况下做任何需要的事情,重复意味着回到第1步。

(这个过程是大型计算机用于合并卡片堆栈并具有特定名称的过程,但我一生都记不起来了!)

干杯 -

于 2014-01-21T17:36:06.277 回答