高木さんBlog高木さん

Day2 备战CCF-CSP练习

高木さん·2024-10-09 09:38·14 次阅读

Day2 备战CCF-CSP练习

Day2

题目描述#

请你写一个命令行分析程序,用以分析给定的命令行里包含哪些选项。

每个命令行由若干个字符串组成,它们之间恰好由一个空格分隔。

这些字符串中的第一个为该命令行工具的名字,由小写字母组成,你的程序不用对它进行处理。

在工具名字之后可能会包含若干选项,然后可能会包含一些不是选项的参数。

选项有两类:带参数的选项和不带参数的选项。

一个合法的无参数选项的形式是一个减号后面跟单个小写字母,如 -a-b

而带参数选项则由两个由空格分隔的字符串构成,前者的格式要求与无参数选项相同,后者则是该选项的参数,是由小写字母,数字和减号组成的非空字符串。

该命令行工具的作者提供给你一个格式字符串以指定他的命令行工具需要接受哪些选项。

这个字符串由若干小写字母和冒号组成,其中的每个小写字母表示一个该程序接受的选项。

如果该小写字母后面紧跟了一个冒号,它就表示一个带参数的选项,否则则为不带参数的选项。

例如,ab:m: 表示该程序接受三种选项,即 -a(不带参数),-b(带参数),以及 -m(带参数)。

命令行工具的作者准备了若干条命令行用以测试你的程序。

对于每个命令行,你的工具应当一直向后分析。

当你的工具遇到某个字符串既不是合法的选项,又不是某个合法选项的参数时,分析就停止。

命令行剩余的未分析部分不构成该命令的选项,因此你的程序应当忽略它们。

输入格式#

输入的第一行是一个格式字符串,它至少包含一个字符,且长度不超过 52

格式字符串只包含小写字母和冒号,保证每个小写字母至多出现一次,不会有两个相邻的冒号,也不会以冒号开头。

输入的第二行是一个正整数 N,表示你需要处理的命令行的个数。

接下来有 N 行,每行是一个待处理的命令行,它包括不超过 256个字符。该命令行一定是若干个由单个空格分隔的字符串构成,每个字符串里只包含小写字母,数字和减号。

输出格式#

输出有 N 行。其中第 i 行以 Case i:开始,然后应当有恰好一个空格,然后应当按照字母升序输出该命令行中用到的所有选项的名称,对于带参数的选项,在输出它的名称之后还要输出它的参数。

如果一个选项在命令行中出现了多次,只输出一次。

如果一个带参数的选项在命令行中出现了多次,只输出最后一次出现时所带的参数。

数据范围#

1N20
对于每组数据,所有命令行工具的名字一定相同,且由小写字母构成。

输入样例:#

Copy
albw:x 4 ls -a -l -a documents -b ls ls -w 10 -x -w 15 ls -a -b -c -d -e -l

输出样例:#

Copy
Case 1: -a -l Case 2: Case 3: -w 15 -x Case 4: -a -b

题目分析#

模拟题 字符串处理
hash表映射记录带不带参数即可,字典序排列用map内部的默认排序即可,剩下的就是字符串分割处理,模仿python3 中的 split()函数实现字符串分割即可,然后参数一个个判断

C++代码#

注意用C++17可以用auto [k , v] : map遍历
C++14不支持,只能auto pair : map 或者 for(map<string , string>::iterator it = map.begin() ; it != map.end() ; it ++)遍历

C++代码#

C++14#

Copy
#include <bits/stdc++.h> using namespace std; string op; map<string , int> opera; int n; string line; vector<string> substr(string line) { vector<string> ans; for(int i = 0 ; i < line.size() ; i ++) { string word = ""; while(i < line.size() && line[i] != ' ') word = word + line[i ++]; ans.push_back(word); } return ans; } int main() { cin >> op; cin >> n; for(int i = 0 ; i < op.size() ; i ++) { string res = "-" + op.substr(i , 1); if(op[i + 1] == ':') opera[res] = 1 , i ++; else opera[res] = 2; } getline(cin , line); for(int l = 1 ; l <= n ; l ++){ getline(cin , line); vector<string> ops = substr(line); map<string , string> res; for(int i = 1 ; i < ops.size() ; i ++) { if(opera[ops[i]] == 0) break; else if(opera[ops[i]] == 2) res.insert({ops[i] , ""}); else { if(i + 1 >= ops.size()) break; res[ops[i]] = ops[i + 1] , i ++; } } cout << "Case " << l << ":"; for(auto it : res) if(it.second != "") cout << " " << it.first << " " << it.second; else cout << " " << it.first; cout << endl; } return 0; }

C++17#

Copy
#include <bits/stdc++.h> using namespace std; string op; map<string , int> opera; int n; string line; vector<string> substr(string line) { vector<string> ans; for(int i = 0 ; i < line.size() ; i ++) { string word = ""; while(i < line.size() && line[i] != ' ') word = word + line[i ++]; ans.push_back(word); } return ans; } int main() { cin >> op; cin >> n; for(int i = 0 ; i < op.size() ; i ++) { string res = "-" + op.substr(i , 1); if(op[i + 1] == ':') opera[res] = 1 , i ++; else opera[res] = 2; } getline(cin , line); for(int l = 1 ; l <= n ; l ++){ getline(cin , line); vector<string> ops = substr(line); map<string , string> res; for(int i = 1 ; i < ops.size() ; i ++) { if(opera[ops[i]] == 0) break; else if(opera[ops[i]] == 2) res.insert({ops[i] , ""}); else { if(i + 1 >= ops.size()) break; res[ops[i]] = ops[i + 1] , i ++; } } cout << "Case " << l << ":"; for(auto [k , v] : res) if(v != "") cout << " " << k << " " << v; else cout << " " << k; cout << endl; } return 0; }
posted @   她说戴了不算給  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示
目录