KMP算法总结&代码

KMP是经典的字符串匹配算法,时间复杂度为o(m+n)

KMP原理

(待补充)

前一阵子自己试着写了一下,代码如下:

/*
*KMP算法实现
*包含两部分:1.模式串前缀函数的计算(预处理)
*			 2.文本与模式串的匹配
*
*模式串前缀函数的计算(预处理):
*假设模式串的长度为len,通过计算模式串从1到len为止的所有子串的
*最大前缀长度,来填充前缀数组。这个前缀满足这种特性:是这个子串的
*真后缀,而且是这个子串的真前缀(即不为子串本身),能满足以上两者
*的最大的那个串,取其长度。例如:abcabc,其中abc既是这个子串的后缀,
*也是这个子串的前缀,并且是最长的,所以其前缀函数值为3.
*
*计算所有子串的前缀函数值:
*从第一个字符开始计算,因为第一个字符没有真前缀,所以取0
*接下来,对每个子串,进行判断,如果失配,则回溯到之前更短的前缀值
*看是否有一个与之可以匹配的。如果匹配,则直接在原有值+1,并移动指针
*例如:abkabcabkabk,当运行到k时,这时前缀指针在c,c!=k,因此失配,通过
*循环返回到abkab的最长前缀值,即2,此时前缀指针指向k,k==k,因此匹配,
*跳出循环,在目前的基础上+1,即为3.前缀指针继续向前移动到a
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
void compute_prefix(char pattern[100],int prefix[100]){
	int len=strlen(pattern),i,prelen;
	prefix[0]=0;
	prelen=0;
	for(i=1;i<len;i++){
		while(prelen>0&&pattern[prelen]!=pattern[i])
			prelen=prefix[prelen-1];
		if(pattern[prelen]==pattern[i])
			prelen++;
		prefix[i]=prelen;
	}
};
int main(){
	char text[1000],pattern[100];
	int prefix[100],i,q=0;
	while(scanf("%s%s",text,pattern)!=EOF){
		compute_prefix(pattern,prefix);
		for(i=0;i<strlen(text);i++){
			while(q>0&&pattern[q]!=text[i])
				q=prefix[q-1];
			if(pattern[q]==text[i])
				q=q+1;
			if(q==strlen(pattern)){
				printf("pattern occurs:%d",i+1-strlen(pattern));
				q=prefix[q-1];
			}
		}
	}
	return 0;
}

  

原文地址:https://www.cnblogs.com/hrlnw/p/3076468.html