fzu 2128 最长子串

            Problem 2128 最长子串 

Accept: 184 Submit: 693
Time Limit: 3000 mSec Memory Limit : 65536 KB
Problem Description
问题很简单,给你一个字符串s,问s的子串中不包含s1,s2…sn的最长串有多长。
Input

输入包含多组数据。第一行为字符串s,字符串s的长度1到10^6次方,第二行是字符串s不能包含的子串个数n,n<=1000。接下来n行字符串,长度不大于100。

字符串由小写的英文字符组成。
Output
最长子串的长度
Sample Input
lgcstraightlalongahisnstreet
5
str
long
tree
biginteger
ellipse
Sample Output
12
分析:这题虽然比赛时没做出来,但是感觉还是不难的。
思路就是:对每个子串取出它在母串的位置,然后按位置排序。在考虑只出现一次情况下,对子串前后的字符长度考虑下,基本就可以做出来了。对细节不好考虑的话,就写一个案例出来,自己观察就好了!
让我无语的数组开小了,开小了,基本我没犯做这错好吧!最后吐槽,hdu上,会返回runtime error,这里只wa!
strstr(a,b)函数是返回,子串b在a中出现的第一次位置,是指针型的。没出现则返回 NULL.如果查找不区分大小写的话可以用 stristr();

#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;

struct a
{
    int star,end;
}vis[1005];

bool cmp(a aa,a bb)
{
    return  aa.star<bb.star;
 } 

char s1[100006],s2[110];

int maxi(int a,int b)
{
    return a>b?a:b;
}

int  t,rel,ans,k;

int main()
{
    while(scanf("%s",s1)!=EOF) 
    {
        scanf("%d",&t);
        rel=0,ans=-1;
        for(int i=1;i<=t;i++)
        {
           scanf("%s",s2);
            char *p;
            char *c=s1;
            while((p=strstr(c,s2))!=NULL)
            { 
                k=p-s1;//子串在母串第一次位置
                for(int i=0;i<strlen(s2);i++)//为第2次找子串准备
                c=(++p); 
                vis[rel].end=k+strlen(s2)-1,vis[rel++].star =k;
            }
         }


         if(!rel)//没有字串,长度就为母串
         {
            printf("%d\n",strlen(s1));
            continue; 
         }

         sort(vis,vis+rel,cmp);

         int j;

         j=vis[0].end;//子串前面的长度

        ans=maxi(ans,j);
         for(int i=1;i<rel;i++)
         {
            j=vis[i].end-vis[i-1].star-1; 
            ans=maxi(ans,j);
         } 

         j=strlen(s1)-1-vis[rel-1].star; //子串后的长度
         ans=maxi(ans,j);

         printf("%d\n",ans);
    }
    return 0;
 } 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值