问题描述
给定一个长度为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中所有字符都是小写英文字母。
提示
枚举所有可能的子串,统计出现次数,找出符合条件的那个
//如果只用一个map,那么只能统计出子串出现最多的次数,不能找到对应条件的子串(因为在子串次数相同的条件下,
//先要看长度,再要看出现顺序,所以要用两个map
#include <stdio.h>
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main()
{
string s, b, ans;
map<string, int>m1; //m1记录的是子串出现的次数
map<string, int> ::iterator it;
map<string, int>m2; //记录的是子串出现的顺序
map<string, int> ::iterator it1, it2;
int n, l, k = 0, max, i, j;
cin>>n;
cin>>s;
l = s.size();
for(i = 0 ; i <= l-n ; i++)
for(j = n ; j <= l-i ; j++)
{
b = s.substr(i, j);
if(m1[b] >= 1)
m1[b]++;
else
{
m1[b] = 1;
m2[b] = k;
}
k++;
}
max = m1.begin()->second;
ans = m1.begin()->first;
for(it = m1.begin() ; it != m1.end(); it++)
{
if((it->second > max) || (it->second == max && it->first.size() > ans.size()))//如果出现次数不同,那么ans肯定要换成出现次数多的。如果出现次数相同,但长度更长,那ans也要换
{
max = it->second;
ans = it->first;
}
else if(it->second == max && it->first.size() == ans.size())//在出现次数、长度都相同的情况下
{
it1 = m2.find(ans);
it2 = m2.find(it->first);
if((*it1).second > (*it).second)//要看出现顺序,这时就要看m2中记录的了
{
max = it->second;
ans = it->first;
}
}
}
cout<<ans<<endl;
}