php实现kmp算法

一直也觉得这个算法没啥大的用处,虽然说这个算法是我第一个学起来觉得挺带劲的算法,可是学会了也没用多少,就没公开,最近学到字符串了,题目对时间复杂度有要求,所以我就把它改成php了,后来觉得挺有用的,就上传上来。

<?php
    $arr_next=array();
    function get_next($str_s,&$arr_next){
        $i=0;            //初始化i为0,因为i指向的是要求next值得字符
        $j=-1;            //j始终指向期望与i指向的字符相等的字符,如果不相等,就只能让j向后退
        $arr_next[0]=-1;    //第一个字符的next值为-1表示j如果退到了这一步就已经无路可退了
        while($i<strlen($str_s)){
            //如果j已经无路可退或者i指向的字符和j指向的字符相等,则i和j同时向后移动
            //原理是如果j已经无路可退了,那么让j++,他就等于0,然后i指向的字符就等于0,那么第i个字符前面的
            //字符和从第一个开始的字符没有一个是相等的。如果它们两个指向的字符相等,那么就让i的next值等于当
            //前的j,表示i指向的字符往前面走的字符和从第一个开始的字符有j个是相等的。
            if($j==-1 || $str_s[$i]==$str_s[$j]){
                ++$j;
                ++$i;
                $arr_next[$i]=$j;
            }else
            //如果当前i指向的字符和j指向的字符不相等,而且j也不是没有退路,那么就让j退到当前字符的next
            //值上去,因为j的next值是下一个和j当前指向的字符具有相同属性的字符,也就是他们两个字符的前面
            //都有x个字符和开头的x个字符是相等的。
                $j=$arr_next[$j];
        }
        unset($arr_next[$i]);
    }
    function kmp($str_s,$str_d){
        $arr_next=array();
        get_next($str_s,$arr_next);
        $i=$j=0;
        //i和j都不能超过他们字符串的长度,加入i超过了,那么必然没有找到目标串,j超过了,那么一定是找到了。
        while($i<strlen($str_s) && $j<strlen($str_d)){
            if($j==-1||$str_s[$i]==$str_d[$j]){
                ++$i;
                ++$j;
            }else
                $j=$arr_next[$j];
        }
        if($j==strlen($str_d))
            return $i-strlen($str_d);
        else
            return 0;
    }
?>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章