给定两个字符串string1和string2,判断string2是否为string1的子串。
输入包含多组数据,每组测试数据包含两行,第一行代表string1(长度小于1000000),第二行代表string2(长度小于1000000),string1和string2中保证不出现空格。
对于每组输入数据,若string2是string1的子串,则输出string2在string1中的位置,若不是,输出-1。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define maxsize 1000005
typedef int position;
void BuildMatch(char *pattern, int *match)
{
position i, j;
int m = strlen(pattern);
match[0] = -1;
for(j = 1; j < m; j ++)
{
i = match[j-1];
while(i >= 0 &&pattern[i+1] != pattern[j])
i = match[i];//相当于递归
if(pattern[i+1] == pattern[j])
match[j] = i + 1;
else
match[j] = -1;
}
}
position KMP(char *string, char *pattern)
{
int n = strlen(string);
int m = strlen(pattern);
position s, p, *match;
if(n < m) return -1;
match = (position *)malloc(sizeof(position)*m);//把match定义成指针类型的 为match分配存储空间 注:这里不乘以m提交的话不对
BuildMatch(pattern, match);
s = p = 0;
while(s < n && p < m)
{
if(string[s] == pattern[p])
{
s ++; p ++;
}
else if(p > 0)
p = match[p-1] + 1; //如果string[s]!=pattern[p]那么p就要回溯到match[p-1]的下一位置
else
s ++;//如果p还在指向模式串的第一个位置 那么就说明s指向的string里的字符与之不等 则需要s指向下一个字符进行比较
}
if(p == m) return (s-m+1);//说明模式串里的字符已全部匹配成功
else return -1;
}
int main()
{
char string[maxsize], pattern[maxsize];
while(~scanf("%s %s", string, pattern))
{
position p =KMP(string, pattern);
printf("%d\n", p);
}
return 0;
}