CCF 201403-3 命令行选项 传送门
一道比较复杂度模拟题, 提交上去突然看到100分有点小惊喜. 之前上一版改了好多次都只有10分20分, 然后重写一版, 结果一次过了.
总结一下需要注意的点
存选项时带着
-
一起存, 这样后面查找选项时可以直接用map
的count
方法, 而不需要拆开-
, 而导致没有考虑到特殊情况, 比如选项可能有-ab
, 而你略过了-
, 读取到它的选项是a
, 这就错了, 而前面说的方法可以避免这一点.使用
stringstream
可方便的将参数选项分离开来, 注意输入n
之后要cin.get()
或getchar()
.使用
set
存储选项, 因为题目要求按字母顺序输出, 而set
可以自动排序, 处理更方便.使用
map
存储选项映射的参数, 这样更新方便注意对题目对参数的描述:
后者则是该选项的参数,是由小写字母,数字和减号组成的非空字符串
, 这意味着参数格式是不规则的, 这道题不用判断参数是否合法
100分代码
#include <algorithm>
#include <iostream>
#include <sstream>
#include <vector>
#include <map>
#include <set>
using namespace std;
map<string, int> orig;
int main()
{
string cmd;
cin >> cmd;
for (size_t i = 0; i < cmd.size(); ++i) {
if (i < cmd.size() - 1 && cmd[i + 1] == ':') {
string tmp;
tmp += '-';
tmp += cmd[i];
orig[tmp] = 1;
++i;
} else {
string tmp;
tmp += '-';
tmp += cmd[i];
orig[tmp] = 0;
}
}
int n, t = 0;
cin >> n;
cin.get();
vector<string> str(n);
for (int k = 0; k < n; ++k) {
getline(cin, str[k]);
stringstream ss(str[k]);
vector<string> param;
string tmp;
while (ss >> tmp) {
param.push_back(tmp);
}
param.erase(param.begin());
set<string> ops;
map<string, string> mp;
for (size_t i = 0; i < param.size(); ++i) {
if (orig.count(param[i]) == 0) break; // 输入选项不存在即不合法,直接跳出
if (orig[param[i]] == 0) { // 无参数的情况.
ops.insert(param[i]);
} else { // 有参数的情况
if (i < param.size() - 1) { // 找参数, 但是参数的格式?
ops.insert(param[i]);
++i;
mp[param[i - 1]] = param[i];
} else break; // 选项是最后一个,说明没有参数
}
}
set<string>::iterator is = ops.begin();
cout << "Case " << ++t << ": ";
while (is != ops.end()) {
cout << *is << ' ';
if (mp.count(*is)) cout << mp[*is] << ' ';
is++;
}
cout << endl;
}
}