题意
模式串在主串中出现了多少次。
样例
Sample Input
3
BAPC
BAPC
AZA
AZAZAZA
VERDI
AVERDXIVYERDIAN
Sample Output
1
3
0
AC代码
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
char S[1000001];
char P[10001];
//int answer[100];
void GetNext(char* p,int* next)
{
int pLen = strlen(p);
next[0] = -1;
int k = -1;
int j = 0;
while (j < pLen ) //这里从pLen-1变成pLen,作用是将next在最后面增加一位(对前几位没任何影响),在第一个结果出来后作j = next[j];,这个数组里的j就是增加得那一位得下标。这样可以使字串右移得位数变短,可以找出重叠的位置;如果不在next数组里增加那一位,则那一位就是定义数组时得默认初始值“0”,右移位数=j-0,就会右移过多,错过重叠的部分,
{
if (k == -1 || p[j] == p[k])
{
k++;
j++;
next[j] = k;
}
else
{
k = next[k];
}
}
/*
cout<<"next数组1:";
for(int i=0;i<pLen;i++)
cout<<next[i]<<" ";
cout<<endl<<endl;
*/
}
int KmpSearch(char* s, char* p,int* next,int count)
{
count=0;
int i = 0;
int j = 0;
int sLen = strlen(s);
int pLen = strlen(p);
while (i < sLen && j < pLen)
{
if (j == -1 || s[i] == p[j])
{
i++;
j++;
}
else
{
j = next[j];
}
if (j == pLen)
{
count++;
// answer[++count]=i - j+1;
// cout<<"第"<<count<<"个结果:"<<answer[count]<<" "<<endl;
//i=i-j+1 //这样说明又回到了暴力方法
j = next[j];
}
}
return count;
}
int main()
{
int next[10009];
int count;
int n;
cin>>n;
while(n--)
{
scanf("%s",P);
scanf("%s",S);
GetNext(P,next);
cout<<KmpSearch(S,P,next,count)<<endl;
}
return 0;
}
题源:acm.hdu.edu.cn/showproblem…