串
分为顺序存储和链式存储,和线性表的操作一样。
KMP模式匹配算法
有一个next数组存储回溯的值。
next求法
123456789
ababaaaba
011234223(next的值)
获值有三种情况
一、j==0 值为0 方便没有对称子串的回溯i无法前进的情况。
二、有对称的子串在前面 值为j 对称的子串个数,为j是因为奇数为对称子串J++后当时的j就在对称的子串的对称轴上,如果是偶数的对称串j++
就是在对称个数最后那里加1。
例如:
12345
ababa
当j=5,前面对称子串为ab所以是3,不是2是因为
12 345
ab|aba
我肯定回溯到3,2前面都判断了。
三、没有对称的子串 值为1
void getNext(int next[],char str[])
{
int i,j;
i=1;
j=0;
next[1]=0;//j=0时
while(i<strlen(str))
{
if(j==0||str[j]==str[i])
{
j++;
i++;
next[i]=j;
}
else
j=next[j];//因为只要有一个无法对称的字符出现,就要回溯
}
}
改良版的next数组获值
void getNext(int next[],char str[])
{
int i,j;
i=1;
j=0;
next[1]=0;//j=0时
while(i<strlen(str))
{
if(j==0||str[j]==str[i])
{
j++;
i++;
if(str[i]!=str[j])
{
next[i]=j;//因为j前面的是和i前面j位相同,所以一旦不同回溯到j.
}
else
{
next[i]=next[j];//因为当前位的数已经不同了,所以直接回到这个数对称的最前面,应对aaaaaab的这种
}
}
else
j=next[j];//因为只要有一个无法对称的字符出现,就要回溯。
}
}
整体的代码
#include<stdio.h>
#include<string.h>
int Index(int next[],char *str1,char *str2);
void getNext(int next[],char str[]);
int main()
{
int next[1000];
char str1[1000],str2[1000];
scanf("%s%s",str1,str2);
int i=Index(next,str1,str2);
if(i)
printf("%d\n",i);
else
{
printf("无法找到\n");
}
}
void getNext(int next[],char str[])
{
int i,j;
i=1;
j=0;
next[1]=0;//j=0时
while(i<strlen(str))
{
if(j==0||str[j]==str[i])
{
j++;
i++;
if(str[i]!=str[j])
{
next[i]=j;//因为j前面的是和i前面j位相同,所以一旦不同回溯到j.
}
else
{
next[i]=next[j];//因为当前位的数已经不同了,所以直接回到这个数对称的最前面,应对aaaaaab的这种
}
}
else
j=next[j];//因为只要有一个无法对称的字符出现,就要回溯。
}
}
int Index(int next[],char *str1,char *str2)
{
getNext(next,str2);
int i,j;
i=0,j=0;
while(i<strlen(str1)&&j<strlen(str2))
{
if(j==0||str1[i]==str2[j])
{
i++;
j++;
}
else
j=next[j];
}
if(j>=strlen(str2))
{
return i-j;//因为j移动的位数就是i从开头移动的位数。
}
else
return 0;
}