2

我有以下代码:

#include <cstring>
#include <boost/functional/hash.hpp>
#include <iostream>

int main(int argc, char **argv)
{
    const char *str1 = "teststring";

    // copy string
    size_t len = strlen(str1);
    char *str2 = new char[len+1];
    strcpy(str2, str1);

    // hash strings
    std::cout << "str1: " << str1 << "; " << boost::hash<const char*>()(str1) << std::endl;
    std::cout << "str2: " << str2 << "; " << boost::hash<const char*>()(str2) << std::endl;

    delete[] str2;

    return 0;
}

我总是得到相同的 str1 哈希(如预期的那样)。但是 str2 不同 - 事实上,每次我运行程序时它都会返回不同的哈希值。

有人可以解释为什么吗?

4

2 回答 2

5

正如 Linuxios 所建议的,它对指针值进行哈希处理,而不是对字符串进行哈希处理。我用这段代码做了一个快速测试:

char str1[] = "teststring";
std::cout << "str1: " << str1 << "; " << boost::hash<const char*>()(str1) << std::endl;
str1[3] = 'x';
std::cout << "str1: " << str1 << "; " << boost::hash<const char*>()(str1) << std::endl;

这是输出。请注意,字符串不同,但由于指针相同,因此哈希匹配。

str1: teststring; 158326806782903
str1: tesxstring; 158326806782903

您需要做的唯一更改是告诉 boost 它正在对 a 进行哈希std::string处理,它会为您提供匹配的哈希值。您的基础数据可以保留char*

std::cout << "str1: " << str1 << "; " << boost::hash<std::string>()(str1) << std::endl;
std::cout << "str2: " << str2 << "; " << boost::hash<std::string>()(str2) << std::endl;

结果:

str1: teststring; 10813257313199645213
str2: teststring; 10813257313199645213
于 2012-06-30T13:59:11.250 回答
0

如果您实际上想要字符串的哈希而不是指针,那么您可以使用boost::hash_range函数或使用 hash_combine 的自定义循环并编写自己的哈希函数对象。 boost::hash<std::basic_string<...> >使用hash_range,has_range依次使用hash_combine.

例如这样的:

struct CStringHash : public std::unary_function<char const*, std::size_t> {
    std::size_t operator()(char const* v) const {
        std::size_t seed = 0;
        for (; *v; ++v) {
            boost::hash_combine(seed, *v);
        }
        return seed;
    }
};
于 2014-06-06T08:05:04.663 回答