[英]boost::hash/std::tr1::hash not returning same hash for copied const char*
我有以下代码:
#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有所不同-实际上,每次我运行程序时,它都会返回不同的哈希值。
有人可以解释为什么吗?
正如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它对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
如果您实际上想要字符串的哈希而不是指针,则可以使用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;
}
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.