#include<stdio.h>
#include<string.h>
#define MAXN 50
int next[MAXN];///next做全局变量直接供自定义函数使用,就不需要传递参数了
int length(char *s)
{
int i,len=0;
for(i=0;s[i]!='\0';i++)
len++;
return len;
}
void getnext(char *s)///串字串,把字串的next的值求出来
{
int j=-1;
int i=0;
next[0]=-1;///一开始字串的第一个位置肯定是没有共同的缀,初始化为-1
int len=length(s);///求出子串的长度
while(i<len)///变量子串
{
if(j==-1||s[i]==s[j])///j=-1,让它如果遇到不相同的进入的条件,
{
++i;++j;///相同的话就同时进一位,j其实就是前缀和后缀的共同部分,共同部分的长度
if(s[i]!=s[j])///这是优化版的next
next[i]=j;///如果进入的条件是-1,而不是相等进入,那么就进入这里,也就告诉next没有共同部分,++j就是0
else
next[i]=next[j];///既然是相同的就继续找相同的共同缀
}
else
j=next[j];///不相同的话,就从前缀后缀相同的部分接下来的位置继续走
}
}
int kmp(char *s1,char *s2)///匹配
{
int i=0,j=0;
int s1_len=length(s1);///s1是主串,求出主串的长度
int s2_len=length(s2);///s2是子串,求出子串的长度
getnext(s2);///找子串的next的值
while(i<s1_len&&j<s2_len)
{
if(j==-1||s1[i]==s2[j])///遇到相同的继续走
{
++i;++j;
}
else
j=next[j];///不同的时候从前面有前缀和后缀相等的部分的接下来的位置继续走
}
if(j==s2_len)///如果跑到了字串的长度,说明是匹配的
return i-j;///返回i-子串的长度,也就是子串在主串的起始位置
return -1;///否则返回-1,表示不匹配
}
int main()
{
char s1[MAXN],s2[MAXN];
int pos;
printf("请输入主串:");
scanf("%s",s1);
printf("请输入要匹配的字串:");
scanf("%s",s2);
pos=kmp(s1,s2);
if(pos==-1)
puts("不匹配");
else
printf("字串在主串的 %d 的位置:\n",pos);
return 0;
}
#include<string.h>
#define MAXN 50
int next[MAXN];///next做全局变量直接供自定义函数使用,就不需要传递参数了
int length(char *s)
{
int i,len=0;
for(i=0;s[i]!='\0';i++)
len++;
return len;
}
void getnext(char *s)///串字串,把字串的next的值求出来
{
int j=-1;
int i=0;
next[0]=-1;///一开始字串的第一个位置肯定是没有共同的缀,初始化为-1
int len=length(s);///求出子串的长度
while(i<len)///变量子串
{
if(j==-1||s[i]==s[j])///j=-1,让它如果遇到不相同的进入的条件,
{
++i;++j;///相同的话就同时进一位,j其实就是前缀和后缀的共同部分,共同部分的长度
if(s[i]!=s[j])///这是优化版的next
next[i]=j;///如果进入的条件是-1,而不是相等进入,那么就进入这里,也就告诉next没有共同部分,++j就是0
else
next[i]=next[j];///既然是相同的就继续找相同的共同缀
}
else
j=next[j];///不相同的话,就从前缀后缀相同的部分接下来的位置继续走
}
}
int kmp(char *s1,char *s2)///匹配
{
int i=0,j=0;
int s1_len=length(s1);///s1是主串,求出主串的长度
int s2_len=length(s2);///s2是子串,求出子串的长度
getnext(s2);///找子串的next的值
while(i<s1_len&&j<s2_len)
{
if(j==-1||s1[i]==s2[j])///遇到相同的继续走
{
++i;++j;
}
else
j=next[j];///不同的时候从前面有前缀和后缀相等的部分的接下来的位置继续走
}
if(j==s2_len)///如果跑到了字串的长度,说明是匹配的
return i-j;///返回i-子串的长度,也就是子串在主串的起始位置
return -1;///否则返回-1,表示不匹配
}
int main()
{
char s1[MAXN],s2[MAXN];
int pos;
printf("请输入主串:");
scanf("%s",s1);
printf("请输入要匹配的字串:");
scanf("%s",s2);
pos=kmp(s1,s2);
if(pos==-1)
puts("不匹配");
else
printf("字串在主串的 %d 的位置:\n",pos);
return 0;
}