【发布时间】:2013-12-23 03:01:13
【问题描述】:
我正在尝试实现 Rabin-Karp 来查找子字符串;我被卡在滚动哈希上(尝试使用formula suggested in Wikipedia)。
#define MOD 1000000007
unsigned long long rolling_hash(const char *str)
{
unsigned long long hash = 0;
size_t str_len = strlen(str);
for(int i = 0, k = str_len -1; i < str_len; i++, k--) {
hash = hash + str[i] * pow(257, k);
// hash = hash % MOD;
}
return hash;
}
int main(void)
{
printf("%llu\n", rolling_hash("TestString"));
printf("%llu\n", rolling_hash("estStringh"));
unsigned long long old = rolling_hash("TestString");
// Add a character to the end
// since the last char in old was multiplied by 1, now multiply it by
// the base and then add the _new_ character to the end
old = old * 257 + 'h';
//old = old % MOD;
// Remove a char from the start
// Simply, remove the hash value of the first character
old = old - 'T' * pow(257, 10);;
printf("\n%llu\n", old);
return 0;
}
只要我不引入任何余数运算,上面的代码就可以完美运行;一旦我取消注释我的 % 操作,事情就会崩溃,我从滚动哈希的变化中得到的答案将不等于第二次打印所打印的结果。
janisz 的回答:
在 janisz 的回答中更改哈希生成器的建议使其余部分在添加新字符时起作用,但在删除旧字符时不起作用。
注意:我正在使用我自己的 pow 函数来与unsigned long long合作
【问题讨论】:
-
注释行有什么问题?
%真正的意思是模数。 -
@Palec:请检查已编辑的问题。 (旁注:% 真正表示余数,而不是模数)(stackoverflow.com/questions/9284644/…)
标签: c++ c string algorithm hash