【问题标题】:Suggestions regarding a string hashing function which ignores ordering of characters关于忽略字符排序的字符串散列函数的建议
【发布时间】:2015-03-08 21:14:03
【问题描述】:

我需要 C++ 中 unordered_map<string, int> 的散列函数。我需要根据内容对密钥进行散列,但它不应该取决于内容的顺序。

例如,在我的地图中,键是字符串,我需要“ac”、“ca”来生成相同的哈希值,但“bb”应该生成不同的哈希值。

我尝试对字符串的内容求和,但我意识到在这种情况下,“ac”和“bb”会生成相同的哈希值。

有类似的问题Does a string hash exist which can ignore the order of chars in this string,但也没有得到回答。

【问题讨论】:

  • 在散列之前对字符串进行排序。这意味着您为 acca 散列 ac,因此它们根据需要散列到相同的值,但 bb(可能)散列到不同的值。
  • ^ 他的意思是“对字符串中的字符进行排序”。
  • 是的。现在对它们进行排序。但是如果有一个线性时间散列函数而没有任何额外的内存来完成这个任务,那就太好了

标签: c++ string hash unordered-map


【解决方案1】:

由于 a * b * c 等价于 a * c * b,您可以将字符相乘而不是相加。

这也应该比在散列之前对每个字符串中的所有字符进行排序要快得多。

【讨论】:

  • 我认为这并不适用于所有情况。例如,如果 ascii 值从 0 开始,则 cc => 9 也 l => 9 。虽然情况可能并非如此,但我猜可能会发生碰撞。如果我能以某种方式避免碰撞,那就太好了。我这样说是因为我知道在我的要求中字符串长度限制在 50 左右。很抱歉没有将此信息添加到问题中。
  • @Anoop:任何散列函数都可能发生冲突;这就是他们的重点。答案中建议的概念几乎可以肯定是您使用原始 ASCII 值(所以a => 97、b => 98、c => 99 等),但您仍然会遇到问题不同的字符串最终产生相同的产品。如果字符串的长度合适,您最终会计算模数某个数字,可能是 2 的幂,例如 2^32 或 2^64,但这不会改变冲突。
  • 您无法避免冲突,因为您将数百位汇总到仅 32 位或仅 64 位。根据定义,这将导致冲突。幸运的是,哈希函数不必保证没有冲突,它只需要确保它们很少发生。字母的 ASCII 值从 65 开始表示大写“A”,97 表示小写“a”,因此通过将这些类型的数字相乘,您极不可能遇到冲突,除非您希望看到发生的特定类型的冲突. (相同的字符乱序。)
猜你喜欢
  • 2013-03-22
  • 2014-01-20
  • 1970-01-01
  • 1970-01-01
  • 2014-02-22
  • 2012-08-08
  • 1970-01-01
  • 1970-01-01
  • 2018-01-14
相关资源
最近更新 更多