KMP实现

确实不好理解啊

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

int next[1005];

/*
	next[j+1] 数组记录的是 p[j]及之前的最大前缀后缀长度 
	next只与模式字符串有关(关键) 
*/ 
void getNext(char *p, int next[])
	{
		int pLen = strlen(p);
		next[0] = -1;
		int k = -1;
		int j = 0;
		while(j < pLen-1){ //这里要注意一下 
			if(k == -1 || p[k] == p[j]){
				++k;
				++j;//这个先加 然后才有next[j] = k  从而达到 next[j+1]表示j及之前前缀后缀长度的目的 
				next[j] = k;
			}
			else{
				k = next[k]; //出现不匹配时候 在字串中寻找匹配 直到k = -1 说明没有匹配字符 
			}
		}			
	}

int kmpSearch(char *s, char *p)
	{
		int i = 0,j = 0;
		int sLen = strlen(s);
		int pLen = strlen(p);
		while(i < sLen && j < pLen){
			if(j == -1 || s[i] == p[j]){
				++i;
				++j;
			}
			else{
				j = next[j];//当出现不匹配时候 直接跳到下一个位置 继续跟i = i+1匹配 
			}
		}
		
		if(j == pLen){//说明找到匹配 
			return i-j; //匹配的位置 
		}
		else{
			return -1; //未匹配 
		}		
	}	
	
int main()
	{
		char s[] = "asvdababccdababc";
		char p[] = "ababc";
		
		getNext(p,next);
		int res = kmpSearch(s,p);
		
		printf("%d\n",res);
		
		return 0;	
	} 

猜你喜欢

转载自blog.csdn.net/Tianweidadada/article/details/80380425