回 帖 发 新 帖 刷新版面

主题:第52次编程比赛新题目

(因为晚上突然有安排,所以只能提早一点了)
(同麻烦bm设置sticky)

给出一个由小写字母组成的串s和一个不超过s的长度的正整数l,求s所有长度不小于l的字串中在s中不重叠地重复出现次数最多的子串。只要输出这个子串出现的次数就行了。

特别强调:子串不是子序列,必须是从s截出来连续的一段。s也是自身的子串。

例如

s = "abcabc", l = 3,

那么输出2,因为所求的子串是abc。

再例如

s = "ababa", l = 3,

那么输出1,长度不小于3的字串包括aba, bab, abab, baba, ababa。其中后面四个显然都只出现一次。前一个aba和后一个aba重叠了一个a,所以只能算不重叠地出现了一次。

实现接口

int solve(const char *s, int l);

s和l意思如上。通过返回值返回答案。

回复列表 (共38个回复)

21 楼

数据范围有多大啊?

22 楼

#include <cstring> 
#include <iostream> 

using namespace std; 

int count(const char *s,char *t,int start) 

     
    int i,j; 
    int flag = 1; 
     
    i = start; 
    j = 0; 
     
    if( s==NULL || t==NULL ) 
         return 0; 
          
    while( *(s+i)!='\0' ) 
    { 
                    
         while(*(t+j)!='\0') 
         { 
              
              if( *(t+j) != *(s+i) )          
                  
                  break; 
               
              else 
              { 
                    
                 i++; 
                 j++;          
                    
              } 
                    
         } 
          
         if( strlen(t) == j )    
         { 
              
             flag++; 
             j = 0; 
              
             } 
         else 
         { 
              
             j = 0; 
             i = i-j+1; 
              
             }     
       
    } 
     
    return flag; 
     


char* make(const char *s,int start,int l) 

    
     char *p; 
      
     int n = strlen(s);   
      
     p = (char *)malloc((l+1)*sizeof(char)); 
      
     int j,i; 
     for( j = 0,i = start;j < l;j++,i++ ) 
     { 
           
         *(p+j) = *(s+i);    
        
     } 
      
     *(p+j) = '\0'; 
      
     return p;       



int solve(const char *s, int l) 

     
    char *p; 
     
    int n = strlen(s); 
     
    int max=1,flag; 
     
    for(int i = 0;i < n;i++ ) 
    { 
              
       for(int k = l; k < n; k++) 
       { 
                  
          if( (k+i) < n ) 
          {     
              
            p = make(s,i,k+i); 
             
            flag = count(s,p,0);
              
            if(flag > max) 
               
                max = flag; 
             
            free(p);    
         
          } 
        
       } 
           
    }  
     
    return max;  
        

23 楼

这一次在原来的基础上做了一点改进

int solve(const char *s, int l)
{
    int max=1;//表示最大次数 
    int i,j,k,lenth,take,ls,p;
    //ls为原始字符串的长度 
     int a[10000];
    //读取样本字符串的数组 
    int count1=0,t=0;
    //t记录样本字符串在原字符串中出现的次数
    
    for (ls=0;s[ls];ls++) //计算原字符串长度 
    ; 

    for (i=0;i<=ls-l;i++)  //此处i用来控制启示位置,ls-l表示样本字符串活动范围 
    {   
        for (lenth=l;lenth<=ls-i;lenth++)  //lenth表示样本字符串的长度 
        {
            for (take=i,p=0;take<lenth+i;take++,p++)  //读取起始位置为i长度为lenth的字符串 
            {
                a[p]=s[take];
            } 
            
            for (j=0;j<=ls-lenth;)  //在原字符串中开始寻找一样的字符串 
            {
                for (k=j,p=0;k<lenth+j;k++,p++)
                {
                    if (a[p]==s[k])  
                    {
                        count1++; //统计在同样长度下相同字符的个数 
                    }
                    else 
                    {
                        count1=0;
                        break;
                    }
                }

                if (count1==lenth)  //成立则表明有相同的字符串 
                {
                    t++;  //t为次数 
                    if (t>max) max=t;
                    j=j+lenth;// 避免出现重叠例如"ababa" 只能算出现一次"aba" 
                    count1=0;
                }
                else j++;
            }
            t=0;//归零 
          }
     }    
     
     printf("最大次数为%d\n",max);
     return max;//返回最大的次数 
}

24 楼

3q

25 楼

int slove(const char *s,int l)
{
    int n=0,i,j,c,k,p;
    int max=1,m;
    int *next;
    char *d;
    while(s[n]!='\0'){n++;};
    d=(char *)malloc((n+1)*sizeof(char));
    next=(int *)malloc((n+1)*sizeof(int));

    for(;l<n/2+1;l++){
        d[l+1]='\0';
        for(p=0;p<n-2*l+1;p++){
        m=0;
        for(k=0;k<l;k++)
            d[k+1]=s[p+k];
        i=1;j=0;next[1]=0;
        while(i<l){
            if(j==0||d[i]==d[j]){
                i++;j++;
                if(d[i]!=d[j])  
                        next[i]=j;
                else 
                        next[i]=next[j];
            }
            else j=d[j];
        }        
        i=p+l;
        do{
            j=1;
            m++;
            while(i<n&&j<=l){
               
                if(j==0||d[j]==s[i]){
                    i++;
                    j++;
                }
                else
                     j=next[j];
                 }
             }while(j>l);
         if(m>max)  max=m;
     }
 }    
     return max;
}

26 楼

貌似难度比较高啊

27 楼

新手勉力一试 如有错误 希望楼主给予指导
#include<stdio.h>
#include<string.h>
#define N 100
int solve(const char *s, int l)
{    
    int len,k,i,j,m,n;
    int num[50][50];
    len=strlen(s);
    if(l<=len)
    {
        for(i=l;i<=len;i++)
        {
            for(j=0;j<len;j++)
            {
                k=1;
                n=j;
                for(m=j+i;m<len;m++)
                {
                    
                    if(s[n]==s[m])
                    {
                        n++;
                        if((n-j)>=i)
                        {
                            n=j;
                            k++;
                        }
                    }
                    else
                    {
                        m=m+j-n;
                        n=j;
                    }
                }
                num[i][j]=k;
            }
        }
        for(i=0;i<50;i++)
        {
            for(j=0;j<50;j++)
            {
                if(num[0][0]<num[i][j])
                    num[0][0]=num[i][j];
            }
        }
        return num[0][0];
    }
}
void main()
{
    char s[N];
    int l,jg;
    printf("请输入一串字符");
    gets(s);
    printf("请输入一个整数");
    scanf("%d",&l);
    jg=solve(s,l);
    printf("%d",jg);
}

28 楼

int solve(char *s, int l)
{
    int len,len1,i,m=1,k,p;
    len1=len=strlen(s);
    if(l>len)
        exit(0);
    if(l>len/2)
        return 1;
    for(p=0;p<=len-l;p++,len1--)
    {
        k=1;i=0;
        while(l<=(strlen(s+p+l+i)))
        {
            if(!strncmp(s+p,s+p+l+i,l))
            {
                i+=l-1;
                k++;
            }
            i++;
        }
        if(k>m)
            m=k;
    }
    return m;
}

29 楼

/*
(因为l和1很象,所以我用m来代替了,没有问题吧 ?)
(还有个就是楼主没有说串的最大长度不超过多少,所以我偷下懒,直接用int类型来表示了)
*/

#include <stdio.h>
#include <string.h>//strlen

int solve(const char *s, int m);

int main(void)
{
    const char *s = "ababababababababacba";

    printf("%d\n", solve(s,2));

    return 0;
}

int solve(const char *s, int m)
{
    if (m <= 0)
    {
        return 0;
    }
    else
    {
        int length = strlen(s);
        int start1 = 0, start2 = 0;//两个待比较子串的起点
        int i = 0, times = 1, timesMax = 1;//比较时使用的记数器

        for (start1=0; start1 <= (length+1 - (timesMax+1)*m); times = 1,start1++)
        {    
            for (start2=(start1+m); start2 <= (length-m+1); start2++)
            {
                for (i=0; i<m  &&  *(s+start1+i) == *(s+start2+i); i++)
                    ;//判断两个子串是否相同
                if (i == m)//相同
                {
                    times++;
                    start2 += (m-1);
                }
            }

            if (times > timesMax)
            {
                timesMax = times;
            }
        }

        return timesMax;
    }
}

30 楼

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
#define N 1024*8 //s的最大长度
int next[N];
char s[N];
int le;
void get_next(int begin,int end)
{
    int i,j;
    next[begin]=begin-1;
    i=begin;j=begin-1;
    while(i<=end)
    {
        if(j==begin-1||s[i]==s[j])
        {
            i++;
            j++;
            if(s[i]!=s[j])
                next[i]=j;
            else next[i]=next[j];
        }
        else j=next[j];
    }
}

int Index_KMP(int pos,int len1,int tbegin,int tend)
{
    int i=pos;
    int j=tbegin;
    int len2=tend-tbegin+1;
    while(i<len1&&j<=tend)
    {
        if(j==tbegin-1||s[i]==s[j])
        {
            i++;
            j++;
        }
        else j=next[j];
        
    }
    if(j>tend) 
        return  i-len2;
    else 
        return -1;
    
}

int solve(const char *s,int  le)
{
    int flag[N],max;
    max=0;
    memset(flag,0,sizeof(flag));
    int i,len,pos;
    len=strlen(s);
    for(i=0;i<=len-le;i++)
    {
        get_next(i,i+le-1);
        if(flag[i]!=-1)
           flag[i]=1;
        else continue;
        pos=i;
        while(pos!=-1)
        {
            pos=Index_KMP(pos+le,len,i,i+le-1);
            if(pos!=-1)
            {
                flag[pos]=-1;
                flag[i]++;
            }
        }
      if(flag[i]>max)max=flag[i];
    }
    printf("%d\n",max);
    return 0;
}


int main()
{

    scanf("%s%d",s,&le);
    solve(s,le);
    return 0;
}

我来回复

您尚未登录,请登录后再回复。点此登录或注册