题目描述
思路讲解
本题是一个简单的字符串模拟题,这种题目是csp认证第三题的常客
大致思路是用两个bool数组记录某一个选项(0--25下标对应小写字母a--z),第一个数组中无参选项为true,第二个数组中有参选项为true,比如说假如st1[0]==false&&st2[0]==false,意思是下面的命令中不能出现-a的选项(包括有参和无参)
对于每一个命令,首先进行字符串的分割,分割方式推荐使用stringstream技术,具体看下面的文章:
stringstream基础使用(类型转换、分割字符串)
分割之后遍历每一个连续字符串,排除不合法情况,把有参的选项的参数找到并记录,最后统一输出即可,详细看下面的代码和注释
满分代码和注释
#include<iostream>
#include<string>
#include<vector>
#include<sstream>
using namespace std;
const int N=30;
bool st1[N];//无参记录
bool st2[N];//有参记录
string ans[N];//每一个选项对应的参数
int main()
{
string str;
cin>>str;
for(int i=0;i<str.length();i++)//预处理bool数组
if(i+1<str.length()&&str[i+1]==':')st2[str[i]-'a']=true,i++;
else st1[str[i]-'a']=true;
int n;
cin>>n;
getchar();//吸收回车,因为下面有getline
for(int i=1;i<=n;i++)
{
getline(cin,str);
printf("Case %d:",i);
vector<string>sp;
stringstream ss(str);
while(ss>>str)sp.push_back(str);//分割字符串至vector中
for(int j=0;j<26;j++)ans[j].clear();//清空每一个样例的答案
for(int j=1;j<sp.size();j++)
{
if(sp[j][0]!='-'||sp[j][1]<'a'||sp[j].length()!=2)break;//不符合选项的要求
//sp[j][1]<'a'意思是第二位不是小写字母,因为数字和减号的ASCII码值均小于'a'
int k=sp[j][1]-'a';
if(st1[k])ans[k]='#';//随便的值,只要长度大于0就可以与没出现过的选项区分
else if(st2[k]&&j+1<sp.size())j++,ans[k]=sp[j];
else break;
}
for(int j=0;j<26;j++)
{
if(ans[j].size())
{
cout<<" -"<<(char)(j+'a');
if(st2[j])cout<<" "<<ans[j];
}
}
cout<<endl;
}
return 0;
}