power oj 2866青春猪头少年不做怀梦美少女的梦(寻找母串中有多少个子串)

本文深入解析字符串匹配问题,探讨如何在母串中寻找子串出现的次数,通过具体实例和代码实现,阐述了前缀和后缀的概念及其在字符串搜索中的应用。

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;
 
}

最后说两句,写程序这件事,坚持很重要,但同样,效率也很重要。只是做好了打时间战的准备,只是想靠时间磨成元老,是永远不会得到自己想要的东西的。有的人为什么比你强,就是同样的时间,人家比你学到了更多的东西。

加油,自勉。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值