kmp算法理解(求next数组)

数组从0开始计数;

next[0]=-1:如果第一位不匹配,只能把子串右移一位;

设子串当前处在q号位,且与母串不匹配,那next[q]应该为多少呢?

q号位不匹配,那子串肯定要右移,考虑到已经匹配到q号了,那q-1及以前都是匹配的;

可以转而考察k=q-1号位,反正要右移,那不如假设k号位也不匹配(也需要右移),k号位移动到哪儿已经是知道的,即next[k];

假设k号位不匹配,那就应该移动到x=next[k]与k对齐,比较str[x]和str[k]:

         如果相等,那q号位(不匹配时)就应该跟x+1比较,此时next[q]已经找到,q++找下一个;

         如果不相等,那x号位置要按照next[x]右移;

右移结束的条件:1.移到头了;2.str[k]==str[x]找到next[q]了。

kmp算法理解(求next数组)_第1张图片

 

 

#include
#include
#include
using namespace std;

void nextMaker(const string s,int N[]){
    int m = s.size();//模版字符串长度
    N[0] = -1;//0是第一个字符,如果不匹配,那么应该把-1的位置移到当前位置(即字符串往右移一位) 
    for(int q=1;q<=m;q++){//q是当前不匹配的位置 
		int k=q-1;//针对q的每轮计算开始k都在q的前一位,N[k]已经计算出来了 
		int x=N[k];
		while(x>=0&&s[x]!=s[k]){
			x=N[x];
		}
		if(x<0){
			N[q]=0;
			continue;
		}
		if(s[x]==s[k]){
			N[q]=x+1;
			continue;
		}
	}
}

int main(){
	string s = "ababaaababaa";
	int N[100];
	N[0]=-1;
	
	nextMaker(s,N);
	for(int i=0;i<=11;i++){
		printf("N[%d] %d\n",i,N[i]);
	}
} 

 

你可能感兴趣的:(数据结构)