[ code=C C++ ][#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void KmpMatcher(char *sourceText, char *str);
void ComputePrefix(int *pi, char *str);
int main(int argc, char *argv[])
{
char sourceText[] = "DocumentsandSettingsAdministratorLocalSettingsTemporaryInternetFiles";
char str0[] = "Administrator";
char str1[] = "Temporary";
char str2[] = "LocalSettings";
KmpMatcher(sourceText,str0);
KmpMatcher(sourceText,str1);
KmpMatcher(sourceText,str2);
return 1;
}
void KmpMatcher(char *sourceText, char *str)
{
int m = strlen(str);
int n = strlen(sourceText);
int *pi = (int *)malloc(sizeof(int)*m);
int q=-1; // 匹配到的索引号,如果为 m-1 则完全匹配一次
ComputePrefix(pi,str);
for (int i=0;i<n;i++)
{
while(q>=0 && str[q+1]!=sourceText[i])
q = pi[q];
if(str[q+1] == sourceText[i])
q++;
if(q == m-1)
{
printf("%s occurs with shift %d/n",str,(i-m+1));
q = pi[q];//继续下一次匹配
}
}
}
void ComputePrefix(int *pi, char *str)
{
//pi(i) 表示字符串跟源字符串匹配到字符索引为i的字符后,真后缀的最长前缀的索引 比如 ababa pi(4) = 2 (aba)
int m = strlen(str);
pi[0] = -1;
int k=-1;
for (int i=1;i<m;i++)
{
while (k>=0 && str[k+1]!=str[i])
{
k = pi[k];
}
if (str[k+1] == str[i])
{
k++;
}
pi[i] = k;
}
}
[/code ]