问题描述
给定一个长度为n的字符串S,还有一个数字L,统计长度大于等于L的出现次数最多的子串(不同的出现可以相交),如果有多个,输出最长的,如果仍然有多个,输出第一次出现最早的。
输入格式
第一行一个数字L。
第二行是字符串S。
L大于0,且不超过S的长度。
第二行是字符串S。
L大于0,且不超过S的长度。
输出格式
一行,题目要求的字符串。
输入样例1:
4
bbaabbaaaaa
输出样例1:
bbaa
输入样例2:
2
bbaabbaaaaa
输出样例2:
aa
输入样例1:
4
bbaabbaaaaa
输出样例1:
bbaa
输入样例2:
2
bbaabbaaaaa
输出样例2:
aa
数据规模和约定
n<=60
S中所有字符都是小写英文字母。
提示
枚举所有可能的子串,统计出现次数,找出符合条件的那个
注意;题目的要求;1,出现次数最多的。2,若出现次数一样多,则输出长度最长的。3,若长度一样长则输出,出现最早的字符串。
题目要点:枚举所有可能的字符串时,条件的控制,
本题为for(int i=0;i<len;i++)
for(int j=i+n-1;j<len;j++)
这两重循环,字符匹配时使用的kMp算法。
代码:
S中所有字符都是小写英文字母。
提示
枚举所有可能的子串,统计出现次数,找出符合条件的那个
注意;题目的要求;1,出现次数最多的。2,若出现次数一样多,则输出长度最长的。3,若长度一样长则输出,出现最早的字符串。
题目要点:枚举所有可能的字符串时,条件的控制,
本题为for(int i=0;i<len;i++)
for(int j=i+n-1;j<len;j++)
这两重循环,字符匹配时使用的kMp算法。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
void next(char t[],int next[])
{
int i=0,j=-1;
next[0]=-1;
int lent=strlen(t);
while(i<lent)
{
if(j==-1||t[i]==t[j])
{
i++;
j++;
next[i]=j;
}
else
j=next[j];
}
}
int kmp(char s[],char t[])
{
int i=0,j=0;
int lens=strlen(s);
int lent=strlen(t);
int t1=0;
int nex[70];
next(t,nex);
while(i<lens)
{
if(j==-1||s[i]==t[j])
{
i++;
j++;
}
else
j=nex[j];
if(j==lent)
{
j=nex[j];
t1++;
}
}
return t1;
}
int main()
{
char s1[70];
char s[70];
int n;
cin>>n;
cin>>s1;
int max1=-1;
int len=strlen(s1);
if(n>0&&n<len)
{
strncpy(s,s1,n);
s[n]='\0';
int vis=-1;
for(int i=0;i<len;i++)//枚举出所有长度大于n的子串
{
for(int j=i+n-1;j<len;j++)
{
char str[70];
int t=j-i+1;
strncpy(str,s1+i,t);//取s1串中从第i个字符开始的长度为t的字串给str
str[j-i+1]='\0';
int temp=kmp(s1,str);//kmp算法求出该字串在主串中出现的次数
int len1=strlen(str);
if(max1<temp)//记录出现次数最多的子串
{
max1=temp;
vis=t;
strcpy(s,str);
}
if(max1==temp)//若两串出现的次数一样多,则取最长的。
{
if(vis<t)//用小于来控制,得到的是出现最早的子串
{
max1=temp;
strcpy(s,str);
}
}
}
}
cout<<s<<endl;
}
return 0;
}