首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于PHP的Rabin-Karp算法

基于PHP的Rabin-Karp算法
EN

Stack Overflow用户
提问于 2009-09-07 21:25:39
回答 4查看 3K关注 0票数 1

我想知道是否有人可以分享Rabin-Karp算法的源码?

谢谢

EN

回答 4

Stack Overflow用户

发布于 2009-09-07 21:27:30

http://en.wikipedia.org/wiki/Rabin-Karp_string_search_algorithm

http://www.eecs.harvard.edu/~ellard/Q-97/HTML/root/node43.html

这里有几个消息来源。

票数 1
EN

Stack Overflow用户

发布于 2009-09-08 20:39:23

这是this C implementation of the Karp-Rabin algorithm的一个端口

代码语言:javascript
复制
function KR($haystack, $needle) {
    $n = strlen($haystack);
    $m = strlen($needle);
    if ($m > $n) {
        return -1;
    }
    /* Preprocessing */
    $d = 1 << ($m - 1);
    for ($hh = $hn = $i = 0; $i < $m; ++$i) {
        $hh = (($hh<<1) + ord($haystack[$i]));
        $hn = (($hn<<1) + ord($needle[$i]));
    }
    /* Searching */
    $j = 0;
    while ($j <= $n-$m) {
        if ($hh == $hn && substr($haystack, $j, $m) === $needle) {
            return $j;
        }
        if ($j === $n-$m) {
            return false;
        }
        /* Rehashing */
        $hh = (($hh - ord($haystack[$j]) * $d) << 1) + ord($haystack[$j + $m]);
        ++$j;
    }
    return false;
}
票数 1
EN

Stack Overflow用户

发布于 2016-12-07 01:17:40

为了说明起见,这里有一个稍微修改过的版本Gumbo上面的答案,使用了更简单的散列和更清晰的变量命名。

在下面的说明性散列中,我只是将每个字符的ord()值添加到一个表示散列的数字中,然后在推进搜索时减去该值/添加下一个字符的ord()。这是非常容易发生冲突的(因此对生产不好),但如果你只是从概念上学习拉宾-卡普,它更容易理解。

代码语言:javascript
复制
function rk ($needle, $haystack)
{
    $nlen = strlen($needle);
    $hlen = strlen($haystack);
    $nhash = 0;
    $hhash = 0;

    // Special cases that don't require the rk algo:
    // if needle is longer than haystack, no possible match
    if ($nlen > $hlen) {
        return false;
    }
    // If they're the same size, they must just match
    if ($nlen == $hlen) {
        return ($needle === $haystack);
    }

    // Compute hash of $needle and $haystack[0..needle.length]
    // This is a very primitive hashing method for illustrative purposes
    // only. You'll want to modify each value based on its position in
    // the string as per Gumbo's example above (left shifting)
    for ($i = 0; $i < $nlen; ++$i) {
        $nhash += ord($needle[$i]);
        $hhash += ord($haystack[$i]);
    }

    // Go through each position of needle and see if
    // the hashes match, then do a comparison at that point
    for ($i = 0, $c = $hlen - $nlen; $i <= $c; ++$i) {
        // If the hashes match, there's a good chance the next $nlen characters of $haystack matches $needle
        if ($nhash == $hhash && $needle === substr($haystack, $i, $nlen)) {
            return $i;
        }
        // If we've reached the end, don't try to update the hash with
        // the code following this if()
        if ($i == $c) {
            return false;
        }

        // Update hhash to the next position by subtracting the
        // letter we're removing and adding the letter we're adding
        $hhash = ($hhash - ord($haystack[$i])) + ord($haystack[$i + $nlen]);
    }

    return false;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1391011

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档