6.7KMP算法

6.7KMP算法

kpm用途:用于解决字符串模式匹配问题(求一个字符串(模式串)在另外一个字符串(主串)中的位置)。

字符串模式匹配问题暴力解法:

int Index(SString S,SString T){  //SString是存储字符串的结构,实际是一个字符数组,数组的第一个位置存储的是这个字符串的长度
    int i=1,j=1;  //主串和模式串下标指示器
    while(i<=S[0]&&J<=T[0]){
        if(S[i]==T[i]){
            ++i;
            ++j;
        }
        else{
            i=i-j+2;j=1;
        }
    }
    if(j>T[0])
        return i-T[0];
    else 
        return 0;
}

i=i-j+2由来:

[外链图片转存失败(img-ApsJhIgu-1567313241946)(assets/1567309839481.png)]

时间复杂度:

[外链图片转存失败(img-XfPR3RCi-1567313241947)(assets/1567309873693.png)]

kpm算法求解优点:可以把时间复杂度降到线性的数量级。

字符串前缀:字符串除了本身的的全部首部

字符串后缀:字符串除了本身的的全部尾部

最长公共前后缀长度:一个字符串相同的前后缀最长长度。

[外链图片转存失败(img-TJPTKel0-1567313241948)(assets/1567310463278.png)]

next数组:记录了模式串每个位置上发生匹配失败时,下一次和主串位置比对的字符的下标。

如何求next数组:

[外链图片转存失败(img-kmXN0r0I-1567313241948)(assets/1567310625230.png)]

[外链图片转存失败(img-LMP57fUW-1567313241949)(assets/1567310878621.png)]

i是next数组下标计数器,j记录的的是next[i]的值;

@1

[外链图片转存失败(img-9jpH3uuh-1567313241949)(assets/1567310952116.png)]

@2[外链图片转存失败(img-gykLUpro-1567313241950)(assets/1567310979801.png)]

@3[外链图片转存失败(img-7w4MaqAV-1567313241951)(assets/1567311076274.png)]

@4[外链图片转存失败(img-xdZ5H05H-1567313241951)(assets/1567311293249.png)]

求next数组代码:

void get_next(char T[],int next[]){ //基于递推的思想
    i=1;
    next[1]=0;
    j=0;
    while(i<T[0]){
        if(j==0||T[i]=T[j]){
            ++i;
            ++j;
            next[i]=j;
        }
        else j=next[j];
    }

}

为什么加 j==0判断条件,并且加在那里:

[外链图片转存失败(img-PSoLwER4-1567313241952)(assets/1567311525176.png)]

Kmp算法代码:

int Kmp(char S[],cahr T[],int next[]){
    int i=1;j=1;
 while(i<=S[0]&&J<=T[0]){
        if(j==0||S[i]==T[i]){
            ++i;
            ++j;
        }
        else{
            j=next[j];
        }
    }
    if(j>T[0])
        return i-T[0];
    else 
        return 0;
}

为什么加 j==0:

[外链图片转存失败(img-N22hQW42-1567313241952)(assets/1567311890051.png)]

算法效率分析:

[外链图片转存失败(img-4NpObzjx-1567313241953)(assets/1567311915755.png)]

手动求解next数组的值:

[外链图片转存失败(img-WKDDGXKK-1567313241953)(assets/1567311964788.png)]

1)写出字符串

2)标下标

3)求next数组值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值