Description
下面解释一下什么是前缀和后缀:
字符串的前缀就是字符串的任意一个首部,他也是一个字符串,例如”abcd”他的前缀有”a”,”ab”,”abc”,”abcd”,这四个。同样字符串的后缀就是字符串的任意一个尾部,例如”abcd”他的后缀有”d”,”cd”,”bcd”,”abcd”这四个。
现在有一个字符串s我们称为文本串。然后给出m个字符串,这m个字符串我们称为模式串。对于每一个模式串t,我们用p表示在s中有多少个前缀的后缀中出现了t,我们用q表示在s中有多少个后缀的前缀中出现了t。他现在想知道p和q中的最大值。
Input
第一行输入一个字符串s(0<|s|≤2000)
第二行输入一个数m
接下来的m行,每行一个字符串ti
∑|ti|≤2000
Output
对于每一个ti
输出一行,输出p和q的最大值,如果p和q相同则输出p和q中任意一个数。
Sample input
gyfnb
2
a
b
Sample Output
0
1
Hint
对于字符串”a“没有任何一个前缀和后缀中出现了字符串”a“,对于字符串”b”,前缀“gyfnb”的后缀中和后缀“b”的前缀中出现了“b”。
看懂这道题了吗?其实就是:给你一个母串,再给你一个子串,问这个母串里面有多少个子串。
没错就是这么简单。
可是打比赛的时候,程序没过,最大的一个原因就是:自己的能力还是不够。
还有一个原因就是,自己不敢相信自己的理解能力。
下面就说说,到底要怎么找子串:
首先,写一层循环。
因为如果子串和母串相同的话,肯定会首字母相同。如果母串里有一个字母和子串相同,那么就往后遍历len2个字母。如果这len2个字母相同的话,就确定母串中有一个子串。则数量加一。
其实这个思路是很好想的,那么自己在比赛的时候卡在了哪里呢?今天上午这道题依然卡了很久,问了罗应华才知道,原来是卡在了特例上。
就是如果输入是母串和子串都是连续的,例如子串是sssssss,一个子串是sss,那么就会有问题。其实现在自己的问题自己也说不太清楚,可能是今天上午根本就不在状态。
我觉得,会去想一些特例,真的是程序员最基本的一个基本功,比如我今天的特例,我想的是不重复的字符串,可是还是有重复的字符串。
可能写程序的时候,会想不出来。
下面粘上我自己的代码:
但愿明天的状态比昨天更加理想吧。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char ss[2009];
int main()
{
scanf("%s",ss);
int m;
scanf("%d",&m);
int len1=strlen(ss);
while(m--)
{
int p=0;//前缀的后缀
char tt[2001];
memset(tt,0,sizeof(tt));
scanf("%s",tt);
int len2=strlen(tt);
for(int i=0;i<len1;i++)
{
if(ss[i]==tt[0])
{
int ff=1;
for(int j=0;j<len2;j++)
{
if(tt[j]!=ss[i])
{
ff=0;
}
if(j!=len2-1)
i=i+1;
}
if(ff)
{
p=p+1;
}
i=i-len2+1;
}
}
printf("%d\n",p);
}
return 0;
}
最后说两句,写程序这件事,坚持很重要,但同样,效率也很重要。只是做好了打时间战的准备,只是想靠时间磨成元老,是永远不会得到自己想要的东西的。有的人为什么比你强,就是同样的时间,人家比你学到了更多的东西。
加油,自勉。