这道题是我做的第一道KMP的题目,还是依赖于叶大佬帮我改的,在此我之前的文章中曾经记录过KMP求解匹配字符串的位置,这次是匹配出有几个字符串,其实这道题不用KMMP也可以做的,,,
下面是题目:
题意就是母串中仅能包括一个字串是YES,否则是NO。
接下来是我用KMP做出来的代码:
#include <stdio.h>
#include <string.h>
int next[1002] = {-5};
char v[10][10] = {"Nikita","Danil","Olya","Slava","Ann"};
char T[1000];
void get_next(int len2)
{
int k = -1;
int j = 0;
next[j] = k;
while(j<len2)
{
if((k==-1)||(v[j] == v[k]))//判断匹配成功的条件
{
k++;
j++;
next[j] = k; //匹配成功都往后移
}
else{
k = next[k];//匹配不成功,看j串是第几个不成功,假设第n个不成功,即j回溯为next[n-1],找n-1处
//的next值,即为k的下一次的值,然后下一次从k的值处开始匹配。
}
}
}
int index_KMP(int len2,int len1,int pos,int l)
{
int i,j;int ans = 0;
i = pos, j = 0;
while(i<len1)
{
if((j==-1)||(T[i] == v[l][j]))
{
++i;
++j;
}
else
{
j = next[j];
}
if(j == len2){
ans++;
j = next[j-1];
i--;
}
}
// printf("%d\n",ans);
return ans;
}
int main()
{
scanf("%s",T);
int len1 = strlen(T);
int pos = 0;
int index = 0;
for(int i=0;i<5;i++)
{
int len2 = strlen(v[i]);
get_next(len2);
}
for(int i=0;i<5;i++)
{
int len2 = strlen(v[i]);
index += index_KMP(len2,len1,0,i);
}
// printf("%d\n",index);
if(index==1)
printf("YES\n");
else
printf("NO\n");
}
接下来是我从一篇大佬的博客中学会的KMP如何匹配出子串的个数的模板:
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXW=10001,MAXT=1000001;
char W[MAXW],T[MAXT];
int next[MAXW];
int lenW,lenT;
void getnext(int lenW)
{
int i=0,j=-1;
next[i]=-1;
while(i<lenW) {
if(j==-1||W[i]==W[j]) {
next[++i]=++j;
}
else j=next[j];
}
}
int kmp(int pos,int lenW,int lenT)
{
int i=pos,j=0,ans=0;
while(i<lenT) {
if(T[i]==W[j]||j==-1) ++i,++j;
else j=next[j];
if(j==lenW) {
ans++;
j=next[j-1];
i--;
}
}
return ans;
}
int main()
{
int n;
scanf("%d",&n);
while(n--) {
scanf("%s%s",W,T);
lenW=strlen(W);
lenT=strlen(T);
getnext(lenW);
printf("%d\n",kmp(0,lenW,lenT));
}
return 0;
}
继续努力吧!