题目描述
瑞神今年大三了,他在寒假学会了英文的26个字母,所以他很兴奋!于是他让他的朋友TT考考他,TT想 到了一个考瑞神的好问题:给定一个字符串,从里面寻找连续的26个大写字母并输出!但是转念一想, 这样太便宜瑞神了,所以他加大了难度:现在给定一个字符串,字符串中包括26个大写字母和特殊字 符’?’,特殊字符’?'可以代表任何一个大写字母。现在TT问你是否存在一个位置连续的且由26个大写字 母组成的子串,在这个子串中每个字母出现且仅出现一次,如果存在,请输出从左侧算起的第一个出现 的符合要求的子串,并且要求,如果有多组解同时符合位置最靠左,则输出字典序最小的那个解!如果 不存在,输出-1! 这下HRZ蒙圈了,他刚学会26个字母,这对他来说太难了,所以他来求助你,请你帮 他解决这个问题,报酬是可以帮你打守望先锋。
说明:字典序 先按照第一个字母,以 A、B、C……Z 的顺序排列;如果第一个字母一样,那么比较第二 个、第三个乃至后面的字母。如果比到最后两个单词不一样长(比如,SIGH 和 SIGHT),那么把短者排 在前。例如
AB??EFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZ
ABDCEFGHIJKLMNOPQRSTUVWXY
上面两种填法,都可以构成26个字母,但是我们要求字典序最小,只能取前者。
注意,题目要求的是 第一个出现的,字典序最小的!
样例
Input
输入只有一行,一个符合题目描述的字符串。
Output
输出只有一行,如果存在这样的子串,请输出,否则输出-1
样例输入1
ABC??FGHIJK???OPQR?TUVWXY?
样例输出1
ABCDEFGHIJKLMNOPQRSTUVWXYZ
样例输入2
AABCDEFGHIJKLMNOPQRSTUVW??M
样例输出2
-1
思路
首先一串字符串在判断时应该是26个一组进行判断的
①对于长度小于26的字符串,必然不满足条件
②对于长度为26的字符串,遍历字符串,使用数组记录每个字符出现的次数和“?”出现的次数,遍历数组,如果每个字母都没有重复(出现次数<=1)并且“?”出现的次数恰好等于出现次数为0的字母的个数,那么此时满足条件
③如果长度大于26,我们要选取最靠左的并且满足条件的子字符串,从第一个字母开始,向后遍历26个字母,并进行②判断,如果满足条件,则选取这一段,如果不满足条件,后移一个字母继续进行③判断,直至出现符合条件的字符串或者遍历结束
对于输出满足条件的字符串:另设一数组,在遍历记录字母出现次数的数组时,依次将次数为0的字母记录到新数组中,在输出时,遇到“?”就依次按顺序输出该数组中记录的字母
代码
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
int main()
{
string s;
cin>>s;
// cout<<int(s[0]);
int sum1[26]={0};
int sum2[26]={0};
int n=s.size();
int num=0;//用来统计?数量
for(int i=0;i<n;i++)
{
if(s[i]!='?')
{
sum1[int(s[i])-65]++;
}
else num++;
}
if(n==26)//123数据点
{
int index=0;
int a[26];
int k=0,p=0;
for(int i=0;i<n;i++)
{
if(sum1[i]>=2)
{
index=1;//重复不符合要求
}
else if(sum1[i]==0)
{
num--;
a[k]=i+65;
k++;
}
}
if(index==0&&num==0)//不重复且缺失的字母能用?补上
{
for(int i=0;i<n;i++)
{
if(s[i]!='?')
cout<<s[i];
else
{
cout<<char(a[p]);
p++;
}
}
}
else cout<<"-1"<<endl;
}
else
{
int flag=n;
int p=0;
int a[26];//用来记录那些字母没有
for(int i=0;i<n-24;i++)
{
int sum2[26];
memset(sum2,0,sizeof(sum2));
int num2=0;
// int a[26];
memset(a,0,sizeof(a));
int q=0;
//统计各个字母的出现次数
for(int j=i;j<i+26;j++)
{
if(s[j]!='?')
sum2[int(s[j])-65]++;
else
{
num2++;//问号数++
}
}
int index=0;
for(int k=0;k<26;k++)
{
if(sum2[k]>=2)
{
index=1;
}
else if(sum2[k]==0)
{
num2--;
a[q]=k+65;
q++;
}
}
if(index==0&&num2==0)
{
flag=i;
break;
}
}
if(flag!=n)
{
for(int i=flag;i<flag+26;i++)
{
if(s[i]!='?')
cout<<s[i];
else
{
cout<<char(a[p]);
p++;
}
}
cout<<endl;
}
else cout<<"-1"<<endl;
}
}