我正在尝试实现Rabin-Karp算法以查找子字符串;但是我卡在了滚动哈希上(尝试使用维基百科中建议的公式)。
上述代码只要不使用任何余数操作就可以正常工作;一旦取消我注释的
janisz的答案: 像janisz的回答中建议更改哈希生成器,可以使添加新字符时余数起作用,但删除旧字符时则不能。 注意:我正在使用自己的
#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