这种kmp算法很简单
代码也没有网上的那么复杂,简单易懂
void CreatPreFix(char pattern[],int prefix[],int n)
{
int i=0,j=1;
prefix[0]=0;
while(j<n)
{
if(pattern[i]==pattern[j])
prefix[j++]=++i;
else
if(i>0)
i=prefix[i-1];
else
prefix[j++]=0;
}
}
void MovePreFix(int prefix[],int n)
{
for(int i=n-1;i>0;i--)
prefix[i]=prefix[i-1];
prefix[0]=-1;
}
void Kmp_Search(char text[],char pattern[],int n,int prefix[])
{
//text[i] len[text]=m;
//pattern[j] len[pattern]=n;
int m=strlen(text);
int i=0,j=0;
while(i<m)
{
if(j==n-1&&text[i]==pattern[j])
{
printf("Found pattern at %d
",i-j);
j=prefix[j];
}
if(text[i]==pattern[j])
{
i++;
j++;
}
else
{
if(j==-1)
{
j++;
i++;
}
else
j=prefix[j];
}
}
}
int main(){
char text[]="centralchinanormaluniversityofchina";
char pattern[]="china";
int prefix[5];
int n=5;
CreatPreFix(pattern,prefix,n);
MovePreFix(prefix,n);
Kmp_Search(text,pattern,n,prefix);
}
下面是伪代码讲解
KMP算法第一步需要求出字串的prefix前缀式
首先将prefix的第一项设为0
在pattern循环完毕之前
进行pattern[j]和pattern[i]进行比较
if 相等
将此时的i值向右移动一格,i自增
将此时的自增过后的i值赋值给pattern[j]所对应的prefix[j]表
j向右移动
if !相等
如果此时的i值是大于零的
将i项左边一项的prefix值附给i,让i的位置移动到prefix[i-1]的值对应的位置上
如果不相等,而且此时的i已经是0了,如果再-1就变成负数,会让i指向一个不知道的地方
则此时的prefix[j]对应的值为0
将求得的prefix整体向右移动,第一项补-1
开始Kmp_Search算法
首先设定text串(一堆乱七八糟的文本串)的长度为m,用i在text中遍历
pattern串(目标查找串)的长度为n,用j在其中遍历
while(i<m)//在整个文本串中遍历,寻找目标串
if (目标串已遍历到最后&&文本串[j]的字符等于目标串[i])
printf出目标串在文本串中第一次出现的位置
j重新回到prefix[j]所指向的位数
if(目标串[i]==文本串[i])
i++;j++;//i,j整体后移,开始比较下一项是否相等
else//不相等
if既不相等,而且当前的j的prefix[j]的值为-1
i++;j++;i,j整体后移,跳过当前的字符串开始进行下一个字符的比对
否则
pattern当前的j回到prefixtab[j]所指向的pattern的位置
这种简化版的代码容易理解,以后抽时间讲解时如何实现的