如何解决在替换字符串中的单个字符时修改哈希值 (c++)
我正在使用多项式哈希函数来计算字符串的哈希值(仅由小写英文字母组成),如下所示:
int SZ = 105,P = 31;
long long M = 1e12 + 9;
vector <long long> pw;
pw.resize(SZ,1);
for(int i = 1; i < SZ; i++) {
pw[i] = (pw[i - 1] * P) % M;
}
long long calculateHash(string &s) {
long long h = 0;
for(int i = 0; i < s.length(); i++) {
h = (h + (s[i] - 'a' + 1) * pw[i]) % M;
}
return h;
}
当我必须在任何给定位置只替换一个字符时,我不想在 O(N) 时间内重新计算整个字符串的哈希值。所以为了在 O(1) 时间内做到这一点,我做了以下操作:
long long h1 = calculateHash(s1);
long long h2 = calculateHash(s2);
// Only one character differs in `s1` and `s2` at index `idx`
// Modifying hash for h1 to incorporate s2[idx] and removing s1[idx]
h1 = (h1 + ((s2[idx] - s1[idx]) * pw[idx])) % M;
现在当我检查 h1 == h2
时,理想情况下应该是相等的,对吗?它确实适用于较小的字符串,但有时会失败,我得到 h1
的负值,不确定这是溢出问题还是 ((s2[idx] - s1[idx]) * pw[idx])
更负导致 h1 低于零。
有人能建议一种在 O(1) 时间内重新计算哈希值的方法吗?提前致谢!
解决方法
原则上你改变结果值的想法是正确的,但你需要的是一个模运算符,它的结果总是正的,对于负输入数字也是如此。
要使用 C++ 模模拟此行为,您可以执行以下操作:
long long tmp=(h1 + ((s2[idx] - s1[idx]) * pw[idx])) % M;
h1=(tmp+M)%M;
第一行是你做过的同样的操作,第二行使结果为正,因为在C++模运算后,tmp
不能小于-M
。需要额外的模数以确保数字保持小于 M
,即使 tmp
已经是正数。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。