📜  用于模式搜索的 Rabin-Karp 算法的PHP程序(1)

📅  最后修改于: 2023-12-03 15:11:17.574000             🧑  作者: Mango

用于模式搜索的 Rabin-Karp 算法的PHP程序

Rabin-Karp算法是一种基于哈希值的字符串匹配算法,它可以在O(n+m)的时间复杂度内,在一个长度为N的字符串中查找一个长度为M的模式串。

算法原理

Rabin-Karp算法的原理是将模式串和文本串分别看成一个P进制的数(P一般是一个素数),然后比较它们的哈希值。如果哈希值相等,则有可能匹配成功,再进一步比较这两个字符串是否真的相等。如果哈希值不相等,则可以排除掉这个文本位置。

PHP程序实现

下面是一个使用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算法那么高,但由于它的实现比较简单,容易理解和调试,所以在一些小规模的字符串匹配问题中也是很实用的。