题目原文
试题编号: | 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 |
题目大意
但是
解题思路:
附录:
读题读了半老天,智商不够就时间弥补吧。。
我对于
既不是合法的选项,又不是某个合法选项的参数时,
分析就停止。命令行剩余的未分析部分不构成该命令的选项,因此你的程序应当忽略它们。
的理解和第一个case数据
albw:x
ls -a -l -a documents -b
Case 1: -a -l
还有这句条件
然后应当按照字母升序输出该命令行中用到的所有选项的名称
反复琢磨理解力好久,我纠结点在于,首先我按照上述条件,认为 ls -a -l -a documents -b 的Case输出,先排个顺序,-a -a documents -b -l,然后发现到达-a documents就不符合了,因为a后面没有冒号,是一个无参数的,所以应该停止输出才对,所以最终结果应该是只输出一个 -a ,后面都停止执行了。
特意查了“既...又....”关系,并列关系,还有一直漏掉的字眼,“某个”。
既不是合法的选项,又不是某个合法选项的参数时
相当于
if(不是合法选项)
if(也不是某个合法选项的参数)
跳过后面的,停止继续输出,转向下一个Case;
也就是说,在推进到-a documents的时候,连第一个case都没进去,虽然把无参数的-a加了个参数,但是却是合法选项,所以按照这句话
然后应当按照字母升序输出该命令行中用到的所有选项的名称,
也就是选项对了,不触发停止分析的条件,但是由于用到了-a正确的选项,所以只是不输出而已。
突然想起,acm那会说的:这个题我不会,但是AC还是没有问题的。这个题的条件有些理解不了,甚至不知道在说什么,不可理喻,但是A掉应该没问题。
题目理解明白了,但是很不好写啊,写不出来,我想的很好,
遍历,对于任意一行来说,
先对本行所有的选项排序,然后遍历对每一个选项做判断
如果是ls,跳过,
如果是选项没有在给定的格式字符串出现过直接终止,不再继续分析,
如果出现过但是参数的有无不匹配,跳过此处选项继续分析,
如果出现在给定的格式字符串当中的就输出,并且还要有一个flag的标记,再出现不做处理(无参数的)
如果是有参数的就输出最后一个参数
但是实际写起来好费劲,细枝末节的变量和混乱的思维感觉无从下手,改的时候也会很痛苦。
其实
先对本行所有的选项排序,然后遍历对每一个选项做判断
这里我就卡住了,怎样将以回车为结尾的一行记录出选项数目并存储在数组中,感觉像之前那种统计一句话单词数的方法有点笨。。感觉这里应该考察的不是这个点吧。。。因为统计单词数已经算单独的一道题目了。查统计单词的时候遇到的略叼的博客刷题平台
思前想去,第一次写出来的代码
1 #include<algorithm> 2 #include<cstring> 3 #include<cstdio> 4 5 #define M 130//最多差不多130个选项(256/2) 6 #define len 260//每个选项最长260 7 8 using namespace std; 9 char box[53];//格式字符串不超过52 10 11 int appear_from_box[30];//26个字母,作为一个标记记号 12 13 char str[M][len];//将一行存入二维数组 14 int cmp1(const void *a, const void*b) 15 { 16 char *s1 = (char *)a; 17 char *s2 = (char *)b; 18 return strcmp(s1, s2); 19 } 20 int main() 21 { 22 int N; 23 scanf("%s", &box); 24 int boxlen = strlen(box); 25 for(int i = 0; i < boxlen; i ++){ 26 appear_from_box[box[i] - 97] = 1;//无参数为1 27 if(box[i + 1] == ':') 28 appear_from_box[box[i] - 97] = 2;//有参数为2 29 //没出现在格式字符串中的为0 30 } 31 32 scanf("%d", &N); 33 for (int i = 0; i < N; i++) 34 { 35 for(int j = 0; j < M; j ++) 36 memset(str[j], 0, sizeof(str));//二维数组初始化 37 gets(str[i]); 38 int x = 0; 39 int y = 0; 40 int p = 0; 41 int number_option = 1;//一行当中选项的个数 42 while(str[p] != ' '){ 43 str[x][y ++] = str[p ++]; 44 if(str[p] == ' ' && str[p + 1] == '-'){ 45 x ++; 46 number_option ++; 47 p ++; 48 } 49 } 50 51 qsort(str, number_option, sizeof(char)*len, cmp1); 52 53 for(int j = 0; j < number_option; j ++) 54 { 55 printf("%c", str[j]); 56 } 57 } 58 }
我本身想的是,ls -a -l -a documents -b 这样一段字符,存入str数组中,共有N行,那对于第N行来说,整行存到str[N-1]中,而用p作为“指针”,从str【N-1】头开始,往后移动,根据空格、‘是否是-’来判断是否是新的一个选项,如果是,我这里用str来充当二维数组的存储内存,装进str的下一行,具体就是 ls存入str[0],-a存入str[1],-l存入str[2],-a documents存入str[3],-b存入str[4],存完排序,再进行附录下面的那段分析输出,这样本行就结束了,memset初始化,进行下一行的判断。
然而.............
错误1:这个运行报错是42/43/44行,主要是str[]属于一个指针,而‘ ’判断。
看来还要开一个数组来存储。
错误2:另外,这个代码,编译时候,42/43/44过不了编译。
而35/36行,
二维数组初始化的问题。????????????难道是memset(str, 0, sizeof(str))???先搁置,这里用的是save了
for(int j = 0; j < M; j ++)
memset(str[j], 0, sizeof(str);
会导致死循环?反正就是鼠标转圈,然后return结束了。
错误3:还有,这里的冒号asc为五十多,26行会出现问题,也会导致过编译但是转圈return
转用save的代码
1 #include<algorithm> 2 #include<cstring> 3 #include<cstdio> 4 5 #define M 130//最多差不多130个选项(256/2) 6 #define len 260//每个选项最长260 7 8 using namespace std; 9 char box[53];//格式字符串不超过52 10 11 int appear_from_box[30];//26个字母,作为一个标记记号 12 char save[len]; 13 char str[M][len];//将一行存入二维数组 14 int cmp1(const void *a, const void*b) 15 { 16 char *s1 = (char *)a; 17 char *s2 = (char *)b; 18 return strcmp(s1, s2); 19 } 20 int main() 21 { 22 int N; 23 scanf("%s", &box); 24 int boxlen = strlen(box); 25 for(int i = 0; i < boxlen; i ++){ 26 if(box[i] != ':') 27 appear_from_box[box[i] - 97] = 1;//无参数为1 28 if(box[i + 1] == ':') 29 appear_from_box[box[i] - 97] = 2;//有参数为2 30 //没出现在格式字符串中的为0 31 } 32 scanf("%d", &N); 33 for (int i = 0; i < N; i++) 34 { 35 memset(save, 0, sizeof(save));//二维数组初始化 36 gets(save); 37 int x = 0; 38 int y = 0; 39 int p = 0; 40 int number_option = 1;//一行当中选项的个数 41 while(save[p] != ' '){ 42 str[x][y ++] = save[p ++]; 43 // if(save[p] == ' ' && save[p + 1] == '-'){ 44 // x ++; 45 // number_option ++; 46 // p ++; 47 // } 48 } 49 // 50 qsort(str, number_option, sizeof(char)*len, cmp1); 51 52 for(int j = 0; j < number_option; j ++) 53 { 54 printf("%c", str[j]); 55 } 56 } 57 }
这里不知道为什么,对于刚输入
albw:x
4
的样例,42行注释掉没问题,不注释掉就会转圈死循环???是我编译器换掉了????第二天起来再运行就没事了。。。。
调试代码:
1 #include<algorithm> 2 #include<cstring> 3 #include<cstdio> 4 5 #define M 130//最多差不多130个选项(256/2) 6 #define len 260//每个选项最长260 7 8 using namespace std; 9 char box[53];//格式字符串不超过52 10 11 int appear_from_box[30];//26个字母,作为一个标记记号 12 char save[len]; 13 char str[M][len];//将一行存入二维数组 14 int cmp1(const void *a, const void*b) 15 { 16 char *s1 = (char *)a; 17 char *s2 = (char *)b; 18 return strcmp(s1, s2); 19 } 20 int main() 21 { 22 int N; 23 scanf("%s", &box); 24 int boxlen = strlen(box); 25 for(int i = 0; i < boxlen; i ++){ 26 if(box[i] != ':') 27 appear_from_box[box[i] - 97] = 1;//无参数为1 28 if(box[i + 1] == ':') 29 appear_from_box[box[i] - 97] = 2;//有参数为2 30 //没出现在格式字符串中的为0 31 } 32 // getchar(); 33 scanf("%d", &N); 34 getchar(); 35 for (int i = 0; i < N; i++) 36 { 37 memset(save, 0, sizeof(save));//二维数组初始化 38 gets(save); 39 // printf("%s ", save); 40 // printf("%c ", save[0]); 41 int x = 0; 42 int y = 0; 43 int p = 0; 44 int number_option = 1;//一行当中选项的个数 45 while(save[p] != '