KMP算法

问题:很经典,也很难,理解了一个下午。。。终于把KMP算法思想弄明白了。改天继续看看。

昨天写的,今天继续补充,KMP算法是由三个人发明的,KMP就是三个人名字的首字母。

下面开始讲这个经典的算法:

1、刚开始比较时,如果相等,下移;

2、继续比较,遇到不相等的,假设位置为j,然后找j之前最大长度相等的前缀和后缀。这个怎么找不好理解,但理解了就很简单。

用子串(现在作为主串)的第一个字符和j位置之前的第一个字符比较,如果相等,继续比较,第二个字符和j之前的第二个字符往后比较,。。。记录最大长度相等的前缀和后缀。

3、如果没有,则主串和子串都增1。

 

next数组的求法:

首先,初始化。next[0]=-1;next[1]=0;

其次,按照上面2的方法求next[j];其中j指的是子串中出现不匹配的情况,而next[j]本身指的是下次主串要与子串匹配的字符。

最后,当j等于子串长度时,匹配成功。

i-j就是匹配的起始位置,i是主串中最后匹配的位置。

代码:

#include <iostream>
#include <cstring>
using namespace std;
 
void getNext(char *s,int *next)
{
    int k=-1,i=0;
    next[0]=-1;
    while(i<strlen(s)-1)
    {
    if(k==-1||s[i]==s[k])
    {
        k++;
        i++;
        next[i]=k;
    }
    else
    {
        k=next[k];
    }
    }
     
}
 
int KMPMatch(char *s,char *str)
{
    int next[100];
    int i=0,j=0;
    getNext(str,next);
    while(i<strlen(s))
    {
    if(j==-1||s[i]==str[j])
    {
       i++;
       j++;
    }
    else
    {
      j=next[j];
    }
     if(j==strlen(str))
         return i-strlen(str);
    }
    return -1;
}
 
int main()
{
    char *s="abcebabcdecada";
    char *str="abcd";
    int n;
    n=KMPMatch(s,str);
    if(n==-1)
        cout<<"未找到匹配字符串"<<endl;
    else
    cout<<"匹配的起始位置为:"<<n<<endl;
 
    return 0;
}

运行结果:

posted @   xshang  阅读(244)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示