你会如何设计一个完美哈希的函数?

时间:2009-04-09 15:33:20

标签: c++ c string function hash

感兴趣的领域是字符串匹配。假设我有这样的结构。

typedef struct
{
    char *name,
    int (*function)();

} StringArray

StringArray s[] = 
{
    {"George", func1},
    {"Paul",   func2},
    {"Ringo",  func3},
    {"John",   func4},
    {"",       NULL}   /* End of list */ 
}

数组中有固定数量的字符串。它们是硬编码的,如示例中所示。 如果表格发生变化,则需要重新评估散列函数的质量。

我想将哈希函数应用于字符串,如果字符串与数组中的字符串匹配, 然后调用该函数。这需要一个完美的哈希函数。不允许冲突。要求散列的目的是在查找上获得O(1)性能。

您在设计功能时有什么想法?

8 个答案:

答案 0 :(得分:16)

请参阅gperf主页。

答案 1 :(得分:2)

摘要列出了C和C ++。你在寻找哪一个? C和C ++是两种不同的语言,它们的字符串处理和数据结构差异很大(而且C语言在C ++中工作的事实不会改变它)。

具体来说,为什么你想要一个完美的哈希函数?是否要将字符串与函数关联起来,并认为这是一个很好的方法吗?这是某种家庭作业吗?你有理由不使用map<>在C ++中? (或unordered_map<>如果可用?)

如果你确实需要一个完美的哈希,字符串的约束是什么?您想要发送某个固定集吗?怎么样的字符串与其中一个字符串不匹配?你是否愿意接受来自随机字符串的命中,或者是否限制传入字符串的数量?

如果你可以编辑你的问题以包含这样的信息,我们可以提供更多帮助。

编辑(回应前两条评论):

好的,我们应该看看C解决方案,因为你可能想要这个C和C ++工作。你可能想要性能,但你测试过吗?如果我们正在处理I / O系统中的字符串,那么可能会使调度时间相形见绌。

您期待任意字符串。期望一个完美的哈希函数可以避免来自随机数据的所有冲突,所以你需要考虑这一点。

您考虑过trie吗?它可能比完美的哈希函数(或可能不是)更有效,它应该相当容易在C中实现,并且它将避免重做调度字符串列表或可能的冲突的问题。

答案 2 :(得分:1)

答案 3 :(得分:0)

您可以使用地图

std::string foo() { return "Foo"; }
std::string bar() { return "Bar"; }

int main()
{
   std::map<std::string, std::string (*)()> m;
   m["foo"] = &foo;
   m["bar"] = &bar; 
}

答案 4 :(得分:0)

如果冲突绝对不允许,您唯一的选择是跟踪数据库中的每个字符串,这可能不是最好的方法。

我要做的是应用现有的常见强哈希算法之一,例如:MD5或SHA。周围有样品镜像,例如:http://www.codeproject.com/KB/security/cryptest.aspx

答案 5 :(得分:0)

使用平衡二叉树。然后你知道行为总是O(登录)。

我非常不喜欢哈希。人们没有意识到他们的算法带来了多大的风险。他们运行一些测试数据,然后在现场部署。我从未见过部署的哈希算法会检查字段中的行为。

O(log n)几乎总是可以接受代替O(1)。

答案 6 :(得分:0)

本练习的最终结果是

  • 从网上窃取了许多面向字符串的哈希函数。
  • 构建一种工厂类,使用一系列mod运算符值对数据集测试每个函数,寻找适用于该函数的最小完美哈希。
  • 该工厂类的默认构造函数返回一个字符串,它表示一组参数,当使用时选择正确的哈希函数,而mod大小则提供需要最少内存的完美哈希。
  • 在正常使用情况下,您只需使用返回的参数实例化该类,并且该类将自身置于具有所需函数的工作状态。
  • 该构造函数验证没有冲突,如果存在则中止。
  • 在没有找到完美哈希的情况下,它会降级为输入表的排序版本的二进制搜索。

对于我在域中拥有的数组,这看起来效果非常好。 未来可能的优化是在输入的子串上进行相同类型的测试。在示例中,每个音乐家名称的第一个字母足以区分它们。然后需要平衡实际哈希函数的成本 使用的记忆。

感谢所有贡献想法的人。

答案 7 :(得分:-1)

嗯,没有完美的哈希函数。

你有几个可以最大限度地减少碰撞,但没有一个消除它们。

不能告诉一个人:P

编辑: 解决方案无法找到完美的哈希函数。解决方案是了解碰撞。通常,哈希函数具有冲突。这显然取决于数据集和生成的哈希码的大小。