📅  最后修改于: 2023-12-03 15:11:17.574000             🧑  作者: Mango
Rabin-Karp算法是一种基于哈希值的字符串匹配算法,它可以在O(n+m)的时间复杂度内,在一个长度为N的字符串中查找一个长度为M的模式串。
Rabin-Karp算法的原理是将模式串和文本串分别看成一个P进制的数(P一般是一个素数),然后比较它们的哈希值。如果哈希值相等,则有可能匹配成功,再进一步比较这两个字符串是否真的相等。如果哈希值不相等,则可以排除掉这个文本位置。
下面是一个使用PHP实现的Rabin-Karp算法程序,该程序接受两个字符串作为参数,分别为文本串和模式串,然后返回模式串在文本串中的起始位置。
<?php
function rabinKarp($text, $pattern) {
$d = 256; // 字符集大小
$q = 101; // 一个大质数,用于取模运算
$n = strlen($text);
$m = strlen($pattern);
$hashText = 0;
$hashPattern = 0;
$h = pow($d, $m - 1) % $q; // 计算P^(m-1)%q
// 计算模式串的哈希值
for ($i = 0; $i < $m; $i++) {
$hashPattern = ($d * $hashPattern + ord($pattern[$i])) % $q;
}
// 计算文本串中第一个长度为m的子串的哈希值
for ($i = 0; $i < $m; $i++) {
$hashText = ($d * $hashText + ord($text[$i])) % $q;
}
for ($i = 0; $i <= $n - $m; $i++) {
// 如果哈希值相等,则进一步比较这两个字符串是否真的相等
if ($hashPattern == $hashText) {
for ($j = 0; $j < $m; $j++) {
if ($pattern[$j] != $text[$i + $j]) {
break;
}
}
if ($j == $m) {
return $i;
}
}
// 计算文本串中下一个长度为m的子串的哈希值
if ($i < $n - $m) {
$hashText = (($hashText - ord($text[$i]) * $h) * $d + ord($text[$i + $m])) % $q;
if ($hashText < 0) {
$hashText += $q;
}
}
}
return -1; // 匹配失败
}
你可以通过调用rabinKarp函数来实现在文本串中查找某个模式串,例如:
$text = "AbcDefGhiJklMnoPqrStuVwxYz";
$pattern = "DefGhiJkl";
echo rabinKarp($text, $pattern); // 输出 3
Rabin-Karp算法虽然性能不如KMP算法和BM算法那么高,但由于它的实现比较简单,容易理解和调试,所以在一些小规模的字符串匹配问题中也是很实用的。