7-3 字符串模式匹配 (5 分)
给定主串s和模式串p,编写程序输出p在s中出现的首位置,若p不在s中则输出-1。字符串下标从0开始。
输入格式:
输入为2行,第1行主串s,第2行为模式串p。主串和模式串长度不超过100000。
输出格式:
输出为2行,第1行为若干整数,表示模式串p的失败函数值****//这是啥意思,每个整数后一个空格;第2行为一个整数,表示p在s中出现的首位置,若p不在s中则输出-1。
输入样例:
qwerabcabhlk
abcab
输出样例:
-1 -1 -1 0 1
4
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 100001//这个数字必须大
int la,lb;
int next[N];
char a[N],b[N];
//next[i]=j,表示前缀j-1和后缀j-1位一定一样,开始匹配第j位
//所以next[i]=j。然后看后面第i位是不是前缀的第j位,
//是的话就开始比较i+1,否则执行else,j=next[j],就是前面最大的是j,所以第i+1的最大的相同前后缀是next[j]
//++i
//:先增加,后引用,先执行i=i+1;再用运算后的i进行其它计算。
void Next()
{
int i=2,j=0;
for(i=2; i<=lb; i++)
{
while(j>0&&b[i]!=b[j+1])
{
j=next[j];
}
if(b[i]==b[j+1])j++;
next[i]=j;
}
}
int KMP(char a[],char b[])
{
int j=0,t=0;
for(int i=1; i<=la; i++)
{
while(j>0&&b[j+1]!=a[i])
{
j=next[j];
}
if(b[j+1]==a[i])j++;
if(j==lb)
{
t=i-lb+1;//遍历了模式串
}
}
return t;
}
int main()
{
scanf("%s",a+1);// 字符串从[ s地址 + 1 ]开始
la=strlen(a+1);
scanf("%s",b+1);
lb=strlen(b+1);
Next();
int m=KMP(a,b);
for(int i=1;i<=lb;i++){
printf("%d ",next[i]-1);
}
printf("\n%d",m-1);
}