Description
给定两个字符串string1和string2,判断string2是否为string1的子串。
Input
输入包含多组数据,每组测试数据包含两行,第一行代表string1(长度小于1000000),第二行代表string2(长度小于1000000),string1和string2中保证不出现空格。
Output
对于每组输入数据,若string2是string1的子串,则输出string2在string1中的位置,若不是,输出-1。
Sample Input
abc
a
123456
45
abc
ddd
Sample Output
1
4
-1
代码:(用了结构体,写了俩函数,不容易啊,RE了6次,仿的清华大学的不该有错啊,参考了一下别人的,除了调用函数然后写得长了点,也没什么不一样,只是把输入由gets()换为了scanf(%s,data)形式,然后就AC了)
#include <stdio.h>
#include <string.h>
#define maxsize 100000
typedef struct
{
char data[maxsize];
int len;
}ma;
void getnext(ma T, int next[])
{
int j, k;
j = 0;
k = -1;
next[0] = -1;
while (j<T.len - 1)
{
if (k == -1 || T.data[j] == T.data[k])
{
j++;
k++;
if (T.data[j] != T.data[k]) //
next[j] = k; //
else //
next[j] = next[k]; //网上优化的多了这四行
}
else k = next[k]; //如果遇到不匹配,早晚会让k遇到0,从头开始比较
}
}
int kmp(ma S, ma T)
{
int next[maxsize];
int i = 0, j = 0;
int v;
getnext(T, next);
while (i<S.len&&j<T.len)
{
if (j == -1 || S.data[i] == T.data[j])
{
i++; j++;
}
else
j = next[j];
}
if (j >= T.len)
v = i - T.len + 1; //这里要注意+1
else v = -1;
return v;
}
int next[maxsize];
int main()
{
int j;
ma S, T;
while (~scanf("%s%s", S.data, T.data))
{
S.len = strlen(S.data);
T.len = strlen(T.data);
getnext(T, next);
printf("%d\n", kmp(S, T));
}
return 0;
}