问题描述:
输入输出:
解题思路:
首先用将26个字母保存到string变量ans中,find函数返回字符在ans字符串中的索引。s为输入的字符串,b数组用来记录每一个字母在s中的位置 ,l用来保存从开始位置到当前位置已符合条件的字符数,若是l为26,说明找到符合条件的字符串。
具体实现:对输入的字符串s进行判断,从0到到s.length()-1,如果是问号,l++,同时判断一下是否l为26,若是26,tmp记录下当前位置,转到输出操作即可。否则,该字符为大写字母,对应的索引为index=find(string[i]),判断该大写字母是否已经出现过(即a[index]!=1),若没有出现过,则l++,a[index]=1,b[index]=i,然后判读一下l是否为26……;若是该字符已经出现过,那么到当前位置的子串已经不符合条件,调用initial函数,去记录新的可能符合条件的子串,应该直接从b[index]+1的位置开始遍历。
若是找到符合条件的子串,temp记录了该子串最后的位置,于是从temp-25到temp,输出该子串,若是遇到’?’,应该输出a[i]=0的且还没有被输出的最小的字符,用一个last变量去记录最后一个被输出的满足a[i]=0的位置i即可,下次找替换字母的时候,直接从last+1的位置开始遍历。
<note注意::!!该题不是简单的直接从index+1的位置开始新的子串,而是从b[index]+1的位置开始>
实验代码:
#include<iostream>
#include<string>
using namespace std;
string ans="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int l=0;
bool a[26];
void initial()
{
l=0;
for(int i=0;i<26;i++)
a[i]=0;
}
int find(char c)
{
for(int i=0;i<26;i++)
if(c==ans[i])
return i;
}
void getAns(string s)
{
bool flag=0;
int temp;
int len=s.length();
int b[26];
int jilu=0;
for(int i=0;i<len;i++)
{
if(s[i]=='?')
{
l++;
if(l==26)
{
flag=1;
temp=i;
break;
}
continue;
}
int index=find(s[i]);
if(!a[index])
{
a[index]=1;
b[index]=i;
l++;
if(l==26)
{
flag=1;
temp=i;
break;
}
}
else
{
initial();
i=b[index];
}
}
if(flag)
{
int start=temp-25,last=0;
for(int i=start;i<=temp;i++)
{
if(s[i]=='?')
{
for(int j=last;j<26;j++)
{
if(!a[j])
{
s[i]=ans[j];
a[j]=1;
last=j+1;
break;
}
}
}
}
for(int i=start;i<=temp;i++)
cout<<s[i];
cout<<endl;
}
else
cout<<-1<<endl;
}
int main(void)
{
string s;
cin>>s;
initial();
getAns(s);
return 0;
}