串-KMP算法

1.字符串蛮力匹配算法

主串长度是 n

模式串长度为 m

则最大匹配次数是 O(n-m+1),;例如,匹配到主串最后四位就不再匹配了,

#include <iostream>
#include <string> //string要小写,不是大写
using namespace std;
bool strnor();
bool strnor(string T,string S)
{
    int j=0,k=0;
    
    for (int i = 0; i <=T.length()-S.length(); i++)
    {
        if (T[i]==S[0])
        {
            k=i;
            k+=1;
            for(int j=1;j<S.length();j++)
            {
                if (T[k]==S[j])
                {
                    if (T[k]==S[j] && j==S.length()-1)
                        return true;
                    k+=1;
                    continue;
                }
                else   
                  { break;    }          
            }        
        }      
    } 
    return false;  
}
int main()
{
    string T,S;//T是主串,S是模式串
    cin>>T;
    cin>>S;//这样的读入是他不会识别,遇见空格 就会自动划分
    cout<<strnor(T,S);
    system("pause");
    return 0;
}

在这里插入图片描述

最好情况是O(m),即是开始就匹配完成

字符串暴力匹配代码:(非以下,留着以后写)

2.KMP算法

这里非常重要的一点是:

① 如果模式串是诸如ABCDEFGH……这样的,没有重复的字母或者汉字,那么KMP算法和暴力匹配算法一样

② 当然,一般不可能出无重复的,模式串一般都会有重复的,那么在手工计算中只需要考虑模式串而无需在意主串
PS:这里说一下,为什么next数组和字符串编号从1开始,天勤的老师是这么说的,因为大部分学校考题喜欢从1开始,所以我们一般只需要考虑从1开始的,就是那么无奈😂🤣
在这里插入图片描述

2.1 next[]数组手算过程

例如:模式串:ababaaababaa的计算结果为
在这里插入图片描述

在这里插入图片描述
最长的前后缀
计算方式:初始化,next的数组的next[0]=0,next[1]=1, 也有的next[0=-1,next[1]=0,他们之前并无公共部分,这点直接写上去

1.从i=2开始计算,扫描到i位置时,计算[ 0…x], [y…i-1]的最大长度size,当然x≤i-1,
要求是str[0…x]=str[y…i-1],x可以等于y

2.那么next[i]=size+1( 若没有 相同的部分,那么size=0,此时next[i]=1

3.循环执行1,2,直至求出该模式串所有的next值

在这里插入图片描述
看此代码的next赋值语句,只有next[ j+1]=t+1才是赋值语句
,其他的都不是next赋值语句,当我们求next[j]的值时,其实是求next[j-1]+1,
从左到右递归关系,而对于next[j-1],我们知道next[j-]=t (设为t) 表示已知,这个过程已经用了KMP算法的思想,把模式串分为主串和模式串,然后进行前后缀对齐计算
在这里插入图片描述
在这里插入图片描述

2.1 next-val[]数组手算过程在这里插入图片描述

​ 为什么会有nextval[]数组?

​ 当有大量重复的子字符串时,next[]数组会浪费一些时间去做无用的比较,人眼可以看出来

​ 比如当比对到主串的B时,按照next[4]的调到3,拉出

在这里插入图片描述
然后A仍然不对,按照next[]数组,继续向前拉A,直至把
在这里插入图片描述
那为什么此时不直接拉到模式串的第一个字符进行比较呢?
这样就可以省去许多时间,上述重复的A,就是Pj=Pnext[j], A=A, j是当前位置,next[j]比j小,因此Pnex[j]在Pj左方,则此时nextval[j] = nextval[ next[j] ]

因此我们提出nextval[]数组对结果进行改善,
在这里插入图片描述

总结:

1. KMP算法保持主串指针不回溯
2. nex[]数组从左到计算,递推关系是next[j]=next[j-1]+1;
3. next[] 和 nextval[] 选一种即可,当你用代码计算next-val[]的时候,就没有必要计算next[]

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值