题目
试题编号: 201403-3
试题名称: 命令行选项
时间限制: 1.0s
内存限制: 256.0MB
问题描述:
问题描述
请你写一个命令行分析程序,用以分析给定的命令行里包含哪些选项。每个命令行由若干个字符串组成,它们之间恰好由一个空格分隔。这些字符串中的第一个为该命令行工具的名字,由小写字母组成,你的程序不用对它进行处理。在工具名字之后可能会包含若干选项,然后可能会包含一 些不是选项的参数。
选项有两类:带参数的选项和不带参数的选项。一个合法的无参数选项的形式是一个减号后面跟单个小写字母,如"-a" 或"-b"。而带参数选项则由两个由空格分隔的字符串构成,前者的格式要求与无参数选项相同,后者则是该选项的参数,是由小写字母,数字和减号组成的非空字符串。
该命令行工具的作者提供给你一个格式字符串以指定他的命令行工具需要接受哪些选项。这个字符串由若干小写字母和冒号组成,其中的每个小写字母表示一个该程序接受的选项。如果该小写字母后面紧跟了一个冒号,它就表示一个带参数的选项,否则则为不带参数的选项。例如, “ab: m:” 表示该程序接受三种选项,即"-a"(不带参数),“-b”(带参数), 以及"-m"(带参数)。
命令行工具的作者准备了若干条命令行用以测试你的程序。对于每个命令行,你的工具应当一直向后分析。当你的工具遇到某个字符串既不是合法的选项,又不是某个合法选项的参数时,分析就停止。命令行剩余的未分析部分不构成该命令的选项,因此你的程序应当忽略它们。
输入格式
输入的第一行是一个格式字符串,它至少包含一个字符,且长度不超过 52。格式字符串只包含小写字母和冒号,保证每个小写字母至多出现一次,不会有两个相邻的冒号,也不会以冒号开头。
输入的第二行是一个正整数 N(1 ≤ N ≤ 20),表示你需要处理的命令行的个数。
接下来有 N 行,每行是一个待处理的命令行,它包括不超过 256 个字符。该命令行一定是若干个由单个空格分隔的字符串构成,每个字符串里只包含小写字母,数字和减号。
输出格式
输出有 N 行。其中第 i 行以"Case i:" 开始,然后应当有恰好一个空格,然后应当按照字母升序输出该命令行中用到的所有选项的名称,对于带参数的选项,在输出它的名称之后还要输出它的参数。如果一个选项在命令行中出现了多次,只输出一次。如果一个带参数的选项在命令行中出 现了多次,只输出最后一次出现时所带的参数。
样例输入
albw:x
4
ls -a -l -a documents -b
ls
ls -w 10 -x -w 15
ls -a -b -c -d -e -l
样例输出
Case 1: -a -l
Case 2:
Case 3: -w 15 -x
Case 4: -a -b
题目分析(个人理解)
- 题目很长,大意是给出一种命令选项的描述方法,然后输入若干命令,需要按照给出的规则解析指令参数,忽略无效部分,然后按顺序输出有效部分。
- 此题还是先看输入,第一行输入模式串,第二行输入命令行的个数,由于模式串每个元素后面是否有冒号存在不同算法,所以,我将有冒号也就是要输出参数的元素放入multi_var = [] 然后将没有冒号,也就是不需要输出参数的元素存入multi_var = [],为什么这么做,因为后续还要判断要输出参数的元素有多个参数出现之后的取值问题。将复杂的问题分解,简单化之后逐一解决。
- 现在处理命令行的问题,命令行中的命令由空格分开,且如果不是带参数的命令长度不可能超过2,(由题意可知,每个符合命令格式的都是一个符号后面带一个字符,如果有参数则字符后面是参数值)也就是合法的长度只有可能是2或三个,如果超过即为不合法。
- 将命令行字符去空格(.split()方法)之后存入cmd[]中,注意split()方法是针对字符串的操作,去空格之后存入列表(返回值是列表)。现在只需判断每个cmd中的第一层列表的元素个数是否是2且第二层列表的第1个值是否是‘-’即可。
for m in range(n):
cmd = input().split()
option = dict()
i = 1
while i<len(cmd):
if len(cmd[i]) == 2 and cmd[i][0] == "-":
- 如果是那么就是符合模式串的输出算法,进行下一步判断,到底是带参数还是不带参数,前面我将带参数和不带参数的模式串分别存放在了列表multi_var = []和single_var = []中。
- 那就只需要cmd中第二层列表的第二个元素,判断在哪个列表中不就完事了?好!问题又来了,输出的格式是满足输出算法的字符和参数,那有些值没参数,有些有参数,参数还要输出最后一次出现的参数,那我只能放在字典中,我使key赋值为符合输出算法的字符,value赋值为每个符合输出算法的参数,如果没有参数,那值设置为空即可。循环一次就更新写入一个item到字典option中,字典对于同一个key赋值两次的时候后一次覆盖前一次,那么就解决了符合输出算法的字符串的值如果有多次的话取最后一次的问题,关于输出还有一个要注意的,就是按照字母升序的顺序输出,那很容易,我直接把keys拿出来搞一个列表用sort()函数排序,然后再按排好的keys输出,然后遍历option中对应的keys的value有没有值,如果有就输出没有就空格和下一个分开就OK。
- 前面第5点已经讲过如何判断带参数还是不带参数的符合输出算法的字符串。之后只需要将带参数的字符对应的参数值赋值给对应的value即可。
- 上代码!!!
form = input()
n = int(input())
single_var = []#存储不带参数的
multi_var = []#存储带参数的
# store options
form += " "
for i in range(len(form)-1):
if form[i+1]==':':
multi_var.append(form[i])
elif form[i]!=':':
single_var.append(form[i])
for m in range(n):
cmd = input().split()
option = dict()
i = 1
while i<len(cmd):
if len(cmd[i]) == 2 and cmd[i][0] == "-":
# is form
if cmd[i][1] in single_var:
# no value
option[cmd[i][1]]=""
i+=1
elif cmd[i][1] in multi_var and i+1 < len(cmd):
# have value
option[cmd[i][1]]= cmd[i+1]
i+=2
else:
# 当你的工具遇到某个字符串既不是合法的选项,又不是某个合法选项的参数时, 分析就停止。
# 命令行剩余的未分析部分不构成该命令的选项,因此你的程序应当忽略它们。
# ls -a -b -c -d -e -l ; after -b is all ignored,because -c
break
else:
# ls -a -l -a documents -b
# -a documents mistake ,so ignore -b
break
"""
其中第 i 行以"Case i:" 开始,然后应当有恰好一个空格,
然后应当按照字母升序输出该命令行中用到的所有选项的名称,对于带参数的选项,在输出它的名称之后还要输出它的参数。如果一个选项在命令行中出现了多次,只输出一次。
如果一个带参数的选项在命令行中出 现了多次,只输出最后一次出现时所带的参数。
"""
keys = list(set(option.keys()))
keys.sort()
print("Case "+str(m+1)+":",end="")
for key in keys:
print(" -"+key,end="")
if option[key]!="":
print(" "+option[key],end="")
print()
总结
CCF CSP认证的难度是按照题目序号升序增加的,所以今天试着挑战一下14年第三题,已经脑阔要爆炸,继续加油!
一个月没跑,感觉要废了,以后在csdn打卡跑步。