先规定一下next数组存的是什么:如果P串的第x个元素与S串的不匹配,回退到P的第next[x]个元素,继续比。
那么next[1]是没有意义的(第一个元素都不一样,只好进入新一轮比较)
next[x]的值有什么特点?P串x之前的这个串,头=尾,这个相等的情况具体多长,就是next[x]的值(再加一,因为我们要的是新位置,前k个能自匹配,新位置就是k+1)
做个练习
a b a b a b c a b a b a b c d a b c
1 1 2 3 4 5 1 2 3 4 5 6 7 8 1 2 3
S串的指针i不回退
情况① S[i] == P[j]
否则:如果j==1,j已经回退到P的第一个字符了,还匹配不上。那么S[i]这趟就结束了,i++,j=1,下一趟重新开始。
如果还没退到P的头,那j=next[j]即可
while (i <= n)
{
if (j == 0)
i++; j=1;
if (S[i] == P[j])
{
i++; j++;
if (j > m) return S + j - 1;
}
else
{
j = next[j];
}
}
void findNext(char * P)
{
int n = strlen(P) -1;
int i = 1, j = 0;
next[1] = 0;// next[1]本身没有意义
while (i < n)
{
//递推,已经知道了next[i],推出next[i+1]是几
if (j == 0)
{
next[i + 1] = 1;
i++;
j = 1;
}
if (P[i] == P[j])
{
/*if (P[i + 1] == P[j + 1])
next[i + 1] = next[next[j + 1]];
else*/
next[i + 1] = j + 1;
i++; j++;
}
else
{
j = next[j];
}
}
}
浙大数据结构编程题34:KMP 串的模式匹配
# include
# include
# define N 1000010
int next[N];
void findNext(char * P)
{
int n = strlen(P) -1;
int i = 1, j = 0;
next[1] = 0;// next[1]本身没有意义
while (i < n)
{
//递推,已经知道了next[i],推出next[i+1]是几
if (j == 0)
{
next[i + 1] = 1;
i++;
j = 1;
}
if (P[i] == P[j])
{
if (P[i + 1] == P[j + 1])
next[i + 1] = next[next[j + 1]];
else
next[i + 1] = j + 1;
i++; j++;
}
else
{
j = next[j];
}
}
}
char * KMP(char * S, char * P)
{
findNext(P);
// S,P从下标为1开始存
int n = strlen(S)-1;
int m = strlen(P)-1;
int i = 0, j = 0;
while (i <= n)
{
if (j == 0)
{
i++; j=1;
}
if (S[i] == P[j])
{
i++; j++;
if (j > m) return S + i - j + 1;
}
else
{
j = next[j];
}
}
return NULL;
}
int main(void)
{
char S[N], P[N];
S[0] = P[0] = 1;
scanf("%s", S + 1);
int n;
scanf("%d", &n);
while (n--)
{
scanf("%s", P+1);
char * ans = KMP(S, P);
if (ans)
printf("%s\n", ans);
else
printf("Not Found\n");
}
return 0;
}
给自己留一个填空题,没事多填填୧⍤⃝
# include
# include
# define N 1000010
char S[N], P[N];
int n, m; //n是S的实际长度,m是P的实际长度
int next[N];
void findNext(char * P)
{
}
char * KMP(char * S, char * P)
{
findNext(P);
}
int main(void)
{
scanf("%s%s", S + 1, P + 1);
int n = strlen(S) - 1;
int m = strlen(P) - 1;
char * ans = KMP(S, P);
if (ans)
printf("%s\n", ans);
else
printf("Not Found\n");
return 0;
}