题目描述
解题思路
- 题目中说明按照小写字母升序输出选项,所以可以将答案存储在string数组中,如果该字母为选项,则输出,若为带参选项,则将参数也输出,ans数组存储参数
- 选项有两种,所以首先将第一行格式串读入,判定每个字母是否带参,用两个布尔数组来存储该字母是否带参
- 为了方便字符串的存储,首先利用getline()读取一行的字符串内容
- 再利用stringstream将读取的一行字符串根据空格分层存储在vector数组中
- 然后根据读取到的内容进行判断,有三种情况:为无参选项(ans[i]随意存储一些内容),为有参选项(ans[i]存储数组的下一行),其他不合法则停止解析
- 最后根据ans数组进行答案的输出,凡是命令行中出现的选项,其ans.size()不等于零,输出选项名称,若是带参选项,还要输出ans
代码实现1
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <sstream>
using namespace std;
const int N = 30;
bool op1[N], op2[N]; //op1存储无参数选项,op2存储有参数选项
int n;
string ans[N];
int main()
{
string str;
cin >> str; //读入所有的参数
for (int i = 0; i < str.size(); i ++) //解析参数是否带参数
{
if (i + 1 < str.size() && str[i + 1] == ':') //如果下一位没有越界,并且下一位是冒号,则该位为带参选项
{
op2[str[i] - 'a'] = true; //表明str[i]为带参选项
i ++; //跳过冒号
}
else
{
op1[str[i] - 'a'] = true;//表明str[i]为不带参选项
}
}
cin >> n;
getchar();//过滤回车
for (int C = 1; C <= n; C ++)
{
printf("Case %d:", C);
getline(cin, str); //读入整行需要用到getline,使用getline(如果上一个读入使用的是cin)需要将上一行的回车进行过滤
string t;
stringstream ssin(str);
vector <string> ops;
while(ssin >> t) ops.push_back(t);//将str按空格分层存储在数组
for (int i = 0; i < 26; i ++) ans[i].clear();//将ans清空
for (int i = 1; i < ops.size(); i ++) //第一个是名字,略过
{
if (ops[i][0] != '-' || ops[i][1] < 'a' || ops[i].size() != 2) break;
int k = ops[i][1] - 'a';
if(op1[k])
{
ans[k] = '*';
}
else if(op2[k] && i + 1 < ops.size())
{
ans[k] = ops[i + 1];
i ++;
}
else break;
}
for (int i = 0; i < 26; i ++)
{
if(ans[i].size())
{
cout << " -" << char('a' + i);
if(op2[i])
{
cout << ' ' << ans[i];
}
}
}
cout << endl;
}
return 0;
}
代码实现2
#include <iostream>
#include <unordered_map>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
unordered_map <string, int> m; // <-a, 1/2>
vector <string> work(string str) //利用双指针将串根据空格进行分割
{
vector <string> res;
res.clear();
for (int i = 0; i < str.size(); i ++)
{
int j = i; //i是字符
string t = "";
while (j < str.size() && str[j] != ' ') j ++; //j = str.size() 或 str[j] = ' '
t = str.substr(i, j - i);
res.push_back(t);
//cout << t << " ";
i = j;
}
return res;
}
int main()
{
string str;
cin >> str;
for (int i = 0; i < str.size(); i ++) //将格式串是否带参存储起来
{
string t = "-";
t += str[i];
if (str[i] == ':') continue;
if ((i < str.size() - 1 && str[i + 1] != ':') || i == str.size() - 1) m[t] = 1;
else m[t] = 2;
//cout << str[i] << " " << m[str[i]] << endl;
}
int n;
cin >> n;
getchar(); //读取回车
for (int i = 1; i <= n; i ++)
{
str = "";
getline(cin, str); //读取整一行字符串
//cout << str << endl;
vector <string> txt;
txt.clear();
txt = work(str);//将这行串根据空格进行拆分
unordered_map <string, string> res; //<选项,参数》
res.clear();
for (int j = 1; j < txt.size(); j ++)
{
string x = txt[j];
//if (x == "ls") continue; //这句话千万不能写,命令行的第一个单词可能并不是ls。。写了就0分。。
if (m[x] == 1)
{
res[x] = "*";
}
else if (m[x] == 2 && j < txt.size() - 1)
{
res[x] = txt[ ++ j];
}
else break;
}
unordered_map <string, int> f;
f.clear();
sort(txt.begin(), txt.end());
printf("Case %d:", i);
for (auto x : txt)
{
if (res[x] != "" && f[x] == 0)
{
f[x] = 1;
cout << " " << x;
if (res[x] != "*") cout << " " << res[x];
}
}
cout << endl;
}
return 0;
}
技巧总结
- 模拟题主要要思考如何存储(存储解决问题百分之八十)
- 字符串的存取方式的选择十分的重要
- stringstream 和 vector等常用函数操作要运用熟练(二者结合使用可以是字符串根据空格分层存储)
- string数组从下标0开始存储
- 清空string数组使用clear函数
- 熟练运用字母下标映射的方法