有没有办法用键作为“字符串”编写简单的哈希表,并将值作为频率编写,这样就没有了冲突?不会从哈希表中删除,如果哈希表中已存在该对象,则只需更新其频率(将它们加在一起)。
我在想可能有一种算法可以从字符串中计算一个唯一的数字,该数字将用作索引。
是的,我避免使用包括unordered_map在内的所有STL构造。
答案 0 :(得分:2)
您可以使用任何完美的哈希生成器,如gperf
请点击此处查看列表:http://en.wikipedia.org/wiki/Perfect_hash_function
PS。如果映射的域太大/稀疏,你仍然可能想要使用地图而不是平面数组/向量
答案 1 :(得分:0)
这实际上取决于你所说的'简单'。
std :: map是一个相当简单的类。尽管如此,它还是使用了一个红黑树,其中所有的插入,删除和平衡都被很好地隐藏起来,并且它可以将任何可订购类型作为键处理,任何类型作为值处理。大多数地图类使用类似的实现,并避免任何类型的散列功能。
没有碰撞的哈希并不是一件轻而易举的事。也许最简单的方法是Pearson Hashing。
看起来你有3个选择:
实现您自己的完美哈希类。这将是一个非常好的大小类,具有许多功能和一些相当复杂的算法。我认为这不简单。
下载并使用已经存在的完美哈希库。当然,您必须担心可部署性。
使用STL的地图类。它嵌入式,文档齐全,易于使用,类型灵活,完全跨平台。这似乎是“最简单”的解决方案。
如果我问,你为什么要避免使用STL?
答案 2 :(得分:0)
如果事先知道可能的字符串集,则可以使用完美的哈希函数生成器来执行此操作。但除此之外,你问的是不可能的。
现在,通过使用良好的哈希函数并确保您的表格很大,可以使冲突的可能性极低。你基本上需要一个足够大的表来使调用Birthday Paradox的可能性足够低以适合你。然后你只需使用SHA-1输出的 n 位, 2 ^ n 就是你的表格大小。
我也想知道你是否可以使用Bloom filter并且有一个实际的计数器而不是位。保留一个列表,列出你填充到布隆过滤器中的所有单词以及它们增加的条目(每次都是相同的),你有一个巨大的线性函数,你可能能够解决所有这些个人重新计票。