第四章 串 KMP算法

一、代码实现

int Index_KMP(SString s,sstring T,int next[] ){
    int i=1, j=1;
    while(i<=s.length&&j<=T.length){
        if(j==0] ||s.ch[i]==T.ch[j]){
            ++i;
            ++j;//继续比较后继字符
        }
        else
        j=next[j];//模式串向右移动
    }
    if(j>T.length)
        return i-T.length;//匹配成功
    else
    return 0;
}

二、next数组手算方法

注意:next数组的第一个数只能是0,第二个数只能是1。

例1:模式串为  a,b,a,b,a,a

1.当第3个数不匹配时

我们可知主串的前两个为a,b,其他未知

第四章 串 KMP算法_第1张图片

将模拟串后移,直到遇到可以匹配的字符串,或问号后停止,j指向1

第四章 串 KMP算法_第2张图片

2.当第4个数不匹配时

第四章 串 KMP算法_第3张图片

 第四章 串 KMP算法_第4张图片

3.当第5个数不匹配时

第四章 串 KMP算法_第5张图片

 第四章 串 KMP算法_第6张图片

 4.当第6个数不匹配时

第四章 串 KMP算法_第7张图片

 第四章 串 KMP算法_第8张图片

 三、nextval数组求法

1.代码实现

nextval[1]=0;
for (int j=2;j<=T.length;j++){
    if(T.ch[next[j]]==T.ch[j])
        nextval[j]=nextval[next[j]];
    else
        nextval[j]=next[j];
}

2.例子

第四章 串 KMP算法_第9张图片

(1)我们先得到一个模拟串的next数组,设定一个nextval数组,nextval[1]一定为0。

第四章 串 KMP算法_第10张图片

(2)从第2个开始判断,此时,j==2,next[j]==1,  string[j]==b,

我们使用next[j]作为新的j1,也就是j1==1,string[j1]==a。

因为两次得到的字符一个为a一个为b,不相等,所以nextval[j]等于next[j].

第四章 串 KMP算法_第11张图片

(3)判断第3个,此时,j==3,next[j]==1,  string[j]==a,

我们使用next[j]作为新的j1,也就是j1==1,string[j1]==a。

因为两次得到的字符都是a,相等,所以nextval[j]等于nextval[ next[j] ]。

第四章 串 KMP算法_第12张图片

(4)判断第4个,此时,j==4,next[j]==2,  string[j]==b,

我们使用next[j]作为新的j1,也就是j1==2,string[j1]==b。

因为两次得到的字符都是b,相等,所以nextval[j]等于nextval[ next[j] ]。

第四章 串 KMP算法_第13张图片

(5)判断第5个,此时,j==5,next[j]==3,  string[j]==a,

我们使用next[j]作为新的j1,也就是j1==3,string[j1]==a。

因为两次得到的字符都是a,相等,所以nextval[j]等于nextval[ next[j] ]。

第四章 串 KMP算法_第14张图片

(6)判断第6个,此时,j==6,next[j]==4,  string[j]==a,

我们使用next[j]作为新的j1,也就是j1==4,string[j1]==b。

因为两次得到的字符一个是a一个是b,不相等,所以nextval[j]等于next[j]。

第四章 串 KMP算法_第15张图片

(7)得到最终的优化数组为

第四章 串 KMP算法_第16张图片

 优点:可以减少时间复杂度

你可能感兴趣的:(数据结构学习,算法,数据结构)