Kmp 模板

kmp算法

通过预处理出next表

将字符串匹配复杂度降为O(n+m)

在串与模式匹配的过程中 串下标永远向前走,而模式下标则通过next进行回溯比较,next[0] =-1 是特殊的位置,当回溯到-1时说明当前串与模式无法匹配,需要移动串下标

而在构造next数组的过程中 相当于进行了自身与自身的匹配 所以next数组与源串并没有关系

next数组总等于当前位置所对应的最长前缀最长后缀 相同的长度 只有这样才会在转移的过程中不会遗失可能相等的地方

#include<bits/stdc++.h> 
using namespace std;

const int maxn = 1000010;
int Next[maxn];
void getNext(string str)
{
	int m = str.length();
    Next[0] = -1;
    int j = -1;
    int i = 0;
    while(i<m)
    {
    	if(j==-1 || str[i]==str[j])//如果j为-1 或能够匹配上,则将i j后移并记录Next[i] 为当前的j
        {	
        	i++,j++;
        	Next[i] = j; 
        }   
        else j = Next[j];	//如果匹配不上 则将j回溯
    }	
}

void kmp(string t,string p)
{
	int i=j=0;
    while(i<t.length())
    {
    	if(j==-1||t[i]==p[j])//如果回溯到了开始 或能够匹配上 则将i,j后移
        {
        	i++,j++;	
        }
        else//	匹配不上 回溯j
        	j=Next[j];
        if(j==p.length())	//已经匹配成功
        {
        	cout << i-j+1<<endl;
            j = 0;			//归零j
        }
    }
}

int main()
{
	string s1,s2;
    cin>>s1>>s2; 
    getnext(s2);
    kmp(s1,s2);
    for(int i=1;i<=s2.length();++i)
    	cout <<Next[i] << ' ';
    return 0;
}
posted @ 2019-03-04 23:05  新新人類  阅读(161)  评论(0编辑  收藏  举报