算法训练 字串统计
问题描述
给定一个长度为n的字符串S,还有一个数字L,统计长度大于等于L的出现次数最多的子串(不同的出现可以相交),如果有多个,输出最长的,如果仍然有多个,输出第一次出现最早的。
输入格式
第一行一个数字L。
第二行是字符串S。
L大于0,且不超过S的长度。
输出格式
一行,题目要求的字符串。
输入样例1:
4
bbaabbaaaaa
输出样例1:
bbaa
输入样例2:
2
bbaabbaaaaa
输出样例2:
aa
数据规模和约定
n<=60
S中所有字符都是小写英文字母。
提示
枚举所有可能的子串,统计出现次数,找出符合条件的那个
一看到是字符串匹配问题,立马想起使用KMP,就是总是不对,后来发现KMP的使用有些问题,就这进行了修改之后,还是不能AC。唉,细心方能行的万年船啊,就是因为没有将(出现的字串可以交叉)这句话,直接导致OVER...,经过再次对KMP进行修改,顺利AC!
- #include<stdio.h>
- #include<string.h>
- int len;
- int n;
- int next[10010];
- char mod[61];
- char re[61];
- char ss[1000];
- void get_next(char mod[])
- { int i,j;
- i=0;next[0]=-1;j=-1;
- while(i<n)
- {
- if(j==-1||mod[i]==mod[j])
- {
- ++i;++j;
- if(mod[i]==mod[j])
- next[i]=next[j];
- else
- next[i]=j;
- }
- else
- j=next[j];
- }
- }
- int kmp(char ss1[],char ss2[])
- {
- int i,j;
- int count1=0;
- i=0,j=0;
- while(i<len)
- {
- while(i<len&&j<n)
- {
- if(j==-1||ss1[i]==ss2[j])
- {
- ++i;++j;
- }
- else
- j=next[j];
- }
- if(j==n)
- {
- count1++;
- i=i-j+1;
- j=0;
- }
-
- }
- return count1;
- }
- int tongji(char ss[], char mod[])
- {
- int mark;
- get_next(mod);
- mark=kmp(ss,mod);
- return mark;
- }
- int main()
- {
- int i,j;
- int max;
- int t,m;
- int length;
- while(scanf("%d",&n)!=EOF)
- {
- scanf("%s",ss);
- len=strlen(ss);
- max=0;
- length=0;
- for(;n<=len;n++)
- {
-
- for(i=0;i<len-n+1;i++)
- {
- for(j=0;j<n;j++)
- {
- mod[j]=ss[i+j];
- }
- t=tongji(ss,mod);
- if(t>max)
- {
- max=t;
- length=n;
- for(int k=0;k<length;k++)
- {
- re[k]=mod[k];
- }
- }
- if(t==max&&n>length)
- {
- length=n;
- for(int k=0;k<length;k++)
- {
- re[k]=mod[k];
- }
- }
- }
- }
- for(i=0;i<length;i++)
- {
- printf("%c",re[i]);
- }
- printf("\n");
- }
- return 0;
- }