KMP查找算法

例题 洛谷P3375 KMP模板

 /*
KMP算法
1.最长前缀后缀
2.基于公共最长前缀后缀进行匹配
	失配时,模式字符串向右移动位数:已匹配字符数-失配字符上一位字符所对应的最长前缀后缀位数
3.next数组
	next数组的求法就是最大长度表全部往右移动一位,然后最左边的那个值赋值为-1就可以了
4.通过代码来递推计算next数组

5.next数组的优化
6.完整的kpm算法
*/

 #include<iostream>
#include<string>
#include<vector>
#include<cstring>
using namespace std;
#define MAXN 1000009
int nex[MAXN];
string s, p;
int slen,plen;
vector<int>ans;
void getNext() {
    int t;
	nex[0] = -1;
    for(int i=1;i<plen;i++){
        t=nex[i-1];
        while(p[t+1]!=p[i]&&t>=0){
            t=nex[t];         //不断回溯,找到匹配点
        }
        if(p[t+1]==p[i])
            nex[i]=t+1;
        else
            nex[i]=-1;
    }
}
void kmp() {
	 int i=0,j=0;
	 while(i<slen){
        if(s[i]==p[j]){
            i++;
            j++;
            if(j==plen){
                ans.push_back(i-j+1);
                j=nex[j-1]+1;
            }
        }else{
            if(j==0)
                i++;
            else{
                j=nex[j-1]+1;
            }
        }
	 }
}
int main(){
	 cin>>s>>p;
	 slen=s.size();
	 plen=p.size();
	 getNext();
	 kmp();
	 int len=ans.size();
	 for(int i=0;i<len;i++){
        cout<<ans[i]<<endl;
	 }
     for(int j=0;j<plen;j++){
        cout<<nex[j]+1<<" ";
     }
     cout<<endl;
}


猜你喜欢

转载自blog.csdn.net/qq_43710881/article/details/105710380
今日推荐