第15章字符串匹配

KMP

  1. 当ABABAAB和ABAA进行匹配
  2. ABAB 和ABAA 不匹配的时候,但ABA匹配
  3. 找ABA的最长前缀,直接将匹配子串的头 放到刚刚匹配到的地方
  4. 最长前缀存放在next数组中,next[j]可以通过next[j-1]获得 :动态规划
  5. next[i-1]=j:
    1. 当v==u:next[i]=next[i-1]+1 =j+1
    2. 当v!=u:j=next[j] (往前跳)

文本串指针不动,一直动的是模式串指针

案例–求next数组

模式串索引01234567891011
模式串saeadaeadaeae
next[]-1-10-101234561
  1. 默认next[0]=-1 j=-1
  2. e和s[j+1]比 :e和s[-1+1]=a比:不匹配,j=-1
  3. a和s[j+1]比:a==a : j=j+1 ,j=0
  4. d和s[j+1]比:d!=e :往前跳j=next[j] j=-1 :
    1. d和s[j+1]比:d!=a :j=-1
  5. a和s[j+1]比:a==a:j=0
  6. e和s[j+1]比:e==e:j=1
  7. a和s[j+1]比:a==a:j=2
  8. d和s[j+1]比:d==d:j=3
  9. a和s[j+1]比:a==a:j=4
  10. e和s[j+1]比:e==e:j=5
  11. a和s[j+1]比:a==a:j=6
  12. e和s[j+1]比:e!=d:往前跳,j=next[j],j=next[6],j=2
    1. e和s[j+1]比:e!=d :往前跳,j=next[j],j=next[2],j=0
    2. e和s[j+1]比:e==e :j+1
//获取next数组
int *getNext(const char *t){
    int tlen=strlen(t);
    int *next=(int *)malloc(sizeof(int)*tlen);
    next[0]=-1;
    int j=-1; //j=next[i-1]
    for(int i=1;t[i];i++){ //遍历模式串的每一位
        while(j!=-1 && t[i]!=t[j+1]) //当uv不相等的时候,j才往前跳
        {
            j=next[j];
        }
        //相等的时候就j+1
        if(t[i]==t[j+1])j+=1;
        next[i]=j; //然后将j赋给next[i],完成当前模式串第i位的next赋值
    }
    return next;
}
int KMP(const char *s,const char *t){
    //先获得一个next数组
    int *next=getNext(t);
    int j=-1,tlen=strlen(t);
    for(int i=0;s[i];i++){
        while(j!=-1 && s[i]!=t[j+1]) //当文本串不等于模式串的t[j+1]个字符的时候
            //调整j的位置,在next数组里面(往前跳)
        {
            j=next[j];
        }
        if(s[i]==t[j+1])j+=1; //相等的时候,j+=1
        if(t[j+1]==0){//全都匹配上了,返回起始位置
            {
                return i-tlen+1;
            }

        }
    }
    return -1;
}

#!/usr/bin/python3
# _*_ coding: utf-8 _*_
#
# Copyright (C) 2024 - 2024 Cry, Inc. All Rights Reserved 
#
# @Time    : 2024/4/13 1:44
# @Author  : Cry
# @File    : KMP.py
# @IDE     : PyCharm
def getNext(s):
    slen=len(s)
    next=list(range(slen+1))
    next[0]=-1 # [-1,0,1,2,3,1,2] 第0位为-1
    j=-1
    i=1
    for c in s: #遍历模式串的每一位
        while(j!=-1 and c!=s[j+1]): # uv不相等,往前跳
            j=next[j] #一直往前跳,直到相等为止
        if(c==s[j+1]): #uv相等,j+1
            j+=1
        next[i]=j
        i+=1
    return next
def kmp(s,t):
    next=getNext(t) #获得模式串的next数组
    print(next)
    j=-1
    tlen=len(t)
    for i in range(len(s)):
        while j!=-1 and s[i]!=t[j+1]:
            j=next[j]
        if s[i]==t[j+1]:
            j+=1
        if j+1==tlen: #模式子串都匹配完成,输出起始位置
            return i-tlen+1
    return -1
print(kmp("abcdefghijk","lmn"))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

厨 神

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值