您的位置:首页 > 其它

蓝桥杯--算法训练 字串统计

2015-03-14 20:28 316 查看
问题描述
  给定一个长度为n的字符串S,还有一个数字L,统计长度大于等于L的出现次数最多的子串(不同的出现可以相交),如果有多个,输出最长的,如果仍然有多个,输出第一次出现最早的。
输入格式
  第一行一个数字L。

  第二行是字符串S。

  L大于0,且不超过S的长度。
输出格式
  一行,题目要求的字符串。

  输入样例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算法。

代码:
#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
='\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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: