您的位置:首页 > 理论基础 > 数据结构算法

数据结构实验之串一:KMP简单应用

2017-10-19 01:17 316 查看
Problem Description

给定两个字符串string1和string2,判断string2是否为string1的子串。

Input

输入包含多组数据,每组测试数据包含两行,第一行代表string1(长度小于1000000),第二行代表string2(长度小于1000000),string1和string2中保证不出现空格。

Output

对于每组输入数据,若string2是string1的子串,则输出string2在string1中的位置,若不是,输出-1。

Example Input

abc

a

123456

45

abc

ddd

Example Output

1

4

-1

#include<stdio.h>
#include<stdlib.h>
#include <string.h>
int next[1000000];
char s[1000010],t[1000010];//位数不能少
void getnext()//如果定义了全局变量,可以省略形参
{
int i=0;
int j=-1;
next[0]=-1;
int a=strlen(t);
while(i<a)
{
if(j==-1||t[i]==t[j])
{
i++;
j++;
if(t[i]!=t[j])
{
next[i]=j;
}
else
next[i]=next[j];
}
else
j=next[j];
}

}
void KMP()
{
getnext();
int i=0;
int j=0;
int a=strlen(s);
int b=strlen(t);
while(i<a&&j<b)
{
if(j==-1||s[i]==t[j])
{
i++;
j++;
}
else
j=next[j];
}
if(j==b)
printf("%d\n",i-b+1);
else

4000
printf("%d\n",-1);
}
int main()
{
while(~scanf("%s %s",s,t))
{
KMP();
}
}


下面说一下对KMP的理解:

0、kmp匹配的函数并不难理解,从暴力匹配思路过渡过来,即可。不同的是,匹配不成功,则i不能回溯(在此位置先不动),然后j=next[j]。

1、难点在于求next[]数组:

其实这也是一个匹配的过程,不过是自己配自己。再从KMP函数的思路过渡过来即可。但是还是有几个点比较难理解。

涉及到的点:

- 前缀后缀

- 相同的最大长度的前缀和后缀

- 且要明白j==-1:从0开始,这个表示第一个字符就不匹配。所以i++,j++

- 最好做题从0开始,不要跟书上一样从1开始。(类似此题,如果从1开始,但是两个字符串是从0开始输入的)

- 以后看到这里如果还不理解,看课本P81-84
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: