一直也覺得這個算法沒啥大的用處,雖然說這個算法是我第一個學起來覺得挺帶勁的算法,可是學會了也沒用多少,就沒公開,最近學到字符串了,題目對時間複雜度有要求,所以我就把它改成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;
}
?>