Rabin-Karp 字符串匹配不匹配
Posted
技术标签:
【中文标题】Rabin-Karp 字符串匹配不匹配【英文标题】:Rabin-Karp String Matching is not matching 【发布时间】:2011-05-20 01:56:08 【问题描述】:我一直在研究 C++ 中的 Rabin-Karp 字符串匹配函数,但没有得到任何结果。我有一种感觉,我没有正确计算某些值,但我不知道是哪一个。
原型
void rabinKarp(string sequence, string pattern, int d, int q);
功能实现
void rabinKarp(string sequence, string pattern, int d, int q)
//d is the |∑|
//q is the prime number to use to lessen spurious hits
int n = sequence.length(); //Length of the sequence
int m = pattern.length(); //Length of the pattern
double temp = static_cast<double> (m - 1.0);
double temp2 = pow(static_cast<double> (d), temp); //Exponentiate d
int h = (static_cast<int>(temp2)) % q; //High Order Position of an m-digit window
int p = 0; //Pattern decimal value
int t = 0; //Substring decimal value
for (int i = 1; i < m; i++) //Preprocessing
p = (d*p + (static_cast<int>(pattern[i]) - 48)) % q;
t = (d*t + (static_cast<int>(sequence[i])-48)) % q;
for (int s = 0; s < (n-m); s++) //Matching(Iterate through all possible shifts)
if (p == t)
for (int j = 0; j < m; j++)
if (pattern[j] == sequence[s+j])
cout << "Pattern occurs with shift: " << s << endl;
if (s < (n-m))
t = (d*(t - ((static_cast<int>(sequence[s+1]) - 48)*h)) + (static_cast<int>(sequence[s + m + 1]) - 48)) % q;
return;
在我的函数调用中,我传递 2359023141526739921 作为序列,31415 作为模式,10 作为基数,13 作为素数。我希望有一个实际匹配和一个虚假命中,但我从来没有从函数的匹配部分得到输出语句。我做错了什么?
提前致谢,麦迪逊
【问题讨论】:
【参考方案1】:编写 Rabin Karp 的最大问题是 modulo operator。当两个数字 X 和 Y 以 Q 为模全等时, (X % Q) 应该等于 (Y % Q) 但在您使用的 C++ 编译器上,只有当 X 和 Y 都是正数或都是负数时,它们才会相等。如果 X 为正而 Y 为负,则 (X % Q) 将为正而 (Y % Q) 为负。实际上在这种情况下是 (X % Q)-Q == (Y % Q)。
解决方法是在每个模数之后检查负值,如果有任何要添加 q 到变量,所以你的预处理循环变成:
p = (d*p + pattern[i]) % q;
if ( p < 0 ) p += q;
t = (d*t + sequence[i]) % q;
if ( t < 0 ) t += q;
主循环中的t需要添加类似的检查。
【讨论】:
【参考方案2】:除非您重新定义了^
,否则它是在计算异或,而不是求幂。此外,在执行%
之前,您应该小心溢出int
的最大值。
【讨论】:
谢谢!这有助于解决我遇到的 h 不正确的问题。我不知道 ^ 运算符未定义为求幂。虽然仍然没有得到输出:( 我会验证它的一小部分是否按预期运行,而不是试图让所有东西立即工作。这将帮助您一一找到您的错误。 单步执行 GDB 让我找到了罪魁祸首:在第二个 for 循环中重新计算 t 会导致负数。据我所知,其他一切都按预期工作。以上是关于Rabin-Karp 字符串匹配不匹配的主要内容,如果未能解决你的问题,请参考以下文章