散列函数不严格依赖于字符串键的大小

时间:2013-04-09 16:20:40

标签: c++ string hash hashtable hash-function

我正在创建一个哈希表,我需要创建一个不仅依赖于字符串键大小的哈希函数,因为周期表元素只有1到3个字符。我怎样才能创建一个哈希函数,给我一个可能基于字符串每个字符的字节的索引?

2 个答案:

答案 0 :(得分:5)

几乎字符串上的每个哈希函数都会对字符进行哈希处理;很难看到字符串完全按照它们的长度进行散列。

一个简单的散列函数系列是shift-add-XOR,顾名思义,它使用位移,加法和异或的组合来从字符串中获取散列函数。它易于实现,并且可以很好地分配密钥。

也就是说,如果您保证只使用周期表符号,则可能需要尝试为元素找到完美的哈希函数。这是为您正在使用的数据集定制的哈希函数,从不会发生任何冲突。像gperf这样的工具可以用来创建这样的函数。

希望这有帮助!

答案 1 :(得分:1)

最简单的解决方案是使用现有的解决方案,如FNV。 但要小心 - 一些非常普遍的哈希函数 当给出很多非常短的字符串时,表现不佳(一个 例如,java.lang.String使用)。对于通用哈希 功能,我通常使用类似的东西:

size_t
hash( std::string const& value )
{
    size_t result = 2166136261;
    for ( std::string::const_iterator current = value.begin();
            current != value.end();
            ++ current ) {
        result = 127 * result + static_cast< unsigned char >( *current );
    }
    return result;
}

在慢速乘法的机器上,这稍微快一些 比FNV,我还没有找到一个分布的案例 显着更差。

但是,您提到最大字符串长度为3。 在这种情况下,您可以使用更简单的技术:

size_t
hash( std::string const& value )
{
    union {
        size_t results;
        char input[ sizeof( size_t ) ];
    } working = 0;
    assert( value.size() <= sizeof( size_t ) );
    value.copy( working.input, sizeof( size_t ) );
    return working.results;
}

这两个都保证了所有字符串的唯一哈希值 长度小于sizeof( size_t )的可打印ASCII字符。