问题描述
给定一个长度为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中所有字符都是小写英文字母。
提示
枚举所有可能的子串,统计出现次数,找出符合条件的那个
S中所有字符都是小写英文字母。
提示
枚举所有可能的子串,统计出现次数,找出符合条件的那个
这道题目用枚举法即可,先是定义一个结构体,来存储字符串、数目、长度;初始化
然后枚举所有可能打表,不会超时。打表结束再从i=0开始遍历;
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef struct
{
char str[100];
int num;
int strlen;
} substring;
substring sub[5000];
char s[1005];
int main()
{
memset(s,0,sizeof(s));
//初始化
for(int i=0; i<5000; i++)
{
strcpy(sub[i].str,"\0");
sub[i].num=0;
sub[i].strlen=0;
}
int l;
while(cin>>l>>s)
{
//打表
int h=0;
for(int i=l; i<strlen(s); i++)
{
for(int j=0; j<=strlen(s)-i; j++)
{
int t1=0;
int t2=j;
while(t1<i)
{
sub[h].str[t1]=s[t2];
t1++;
t2++;
}
sub[h].num=1;
sub[h].strlen=i;
h++;
}
}
// for(int i=0; i<h; i++)
// {
// cout<<sub[i].str<<endl;
// }
int min=0;
char cs[5000];
int clen;
for(int i=0; i<h; i++)
{
for(int j=i+1; j<h; j++)
{
if(strcmp(sub[j].str,"***********")==0||strcmp(sub[i].str,"***********")==0)//这里我把遍历过的标记它
continue;
if(strcmp(sub[i].str,sub[j].str)==0)
{
sub[i].num++;
strcpy(sub[j].str,"***********");
sub[i].strlen=strlen(sub[i].str);
}
}
if(min<sub[i].num)//取长度最大的
{
min=sub[i].num;
strcpy(cs,sub[i].str);
clen=sub[i].strlen;
}
if(min==sub[i].num){
if(clen<sub[i].strlen)
{
min=sub[i].num;
strcpy(cs,sub[i].str);
clen=sub[i].strlen;
}
}
}
cout<<cs;
cout<<endl;
for(int i=0; i<5000; i++)//重新初始化
{
strcpy(sub[i].str,"\0");
sub[i].num=0;
sub[i].strlen=0;
}
}
return 0;
}
#include<algorithm>
#include<cstring>
using namespace std;
typedef struct
{
char str[100];
int num;
int strlen;
} substring;
substring sub[5000];
char s[1005];
int main()
{
memset(s,0,sizeof(s));
//初始化
for(int i=0; i<5000; i++)
{
strcpy(sub[i].str,"\0");
sub[i].num=0;
sub[i].strlen=0;
}
int l;
while(cin>>l>>s)
{
//打表
int h=0;
for(int i=l; i<strlen(s); i++)
{
for(int j=0; j<=strlen(s)-i; j++)
{
int t1=0;
int t2=j;
while(t1<i)
{
sub[h].str[t1]=s[t2];
t1++;
t2++;
}
sub[h].num=1;
sub[h].strlen=i;
h++;
}
}
// for(int i=0; i<h; i++)
// {
// cout<<sub[i].str<<endl;
// }
int min=0;
char cs[5000];
int clen;
for(int i=0; i<h; i++)
{
for(int j=i+1; j<h; j++)
{
if(strcmp(sub[j].str,"***********")==0||strcmp(sub[i].str,"***********")==0)//这里我把遍历过的标记它
continue;
if(strcmp(sub[i].str,sub[j].str)==0)
{
sub[i].num++;
strcpy(sub[j].str,"***********");
sub[i].strlen=strlen(sub[i].str);
}
}
if(min<sub[i].num)//取长度最大的
{
min=sub[i].num;
strcpy(cs,sub[i].str);
clen=sub[i].strlen;
}
if(min==sub[i].num){
if(clen<sub[i].strlen)
{
min=sub[i].num;
strcpy(cs,sub[i].str);
clen=sub[i].strlen;
}
}
}
cout<<cs;
cout<<endl;
for(int i=0; i<5000; i++)//重新初始化
{
strcpy(sub[i].str,"\0");
sub[i].num=0;
sub[i].strlen=0;
}
}
return 0;
}