Problem description
Please write a command line analyzer to analyze the options in the given command line. Each command line consists of several strings separated by exactly one space. The first of these strings is the name of the command-line tool, which is made up of lowercase letters. Your program doesn't have to deal with it. There may be several options after the tool name, and then there may be parameters that are not options.
There are two types of options: options with parameters and options without parameters. A legal parameterless option takes the form of a minus followed by a single lowercase letter, such as "- a" or "- b". The options with parameters are composed of two strings separated by spaces. The format of the former is the same as that of the option without parameters, and the latter is the parameters of the option. It is a non empty string composed of lowercase letters, numbers and minus signs.
The author of the command-line tool provides you with a format string to specify which options his command-line tool needs to accept. This string consists of several lowercase letters and colons, each of which represents an option accepted by the program. If the lowercase letter is followed by a colon, it represents an option with parameters, otherwise it is an option without parameters. For example, "ab: m:" means that the program accepts three options, namely "- a" (without parameters), "- b" (with parameters), and "- m" (with parameters).
The author of the command line tool prepared several command lines to test your program. For each command line, your tool should always analyze backwards. When your tool encounters a string that is neither a valid option nor a parameter of a valid option, the analysis stops. The rest of the command line that is not parsed does not constitute options for the command, so your program should ignore them.
Input format
The first line of input is a format string that contains at least one character and is no longer than 52. The format string contains only lowercase letters and colons, ensuring that each lowercase letter appears at most once, without two adjacent colons or starting with a colon.
The second line of input is a positive integer N(1 ≤ N ≤ 20), indicating the number of command lines you need to process.
Next there are N lines, each of which is a command line to be processed, which contains no more than 256 characters. The command line must be composed of several strings separated by a single space. Each string contains only lowercase letters, numbers and minus signs.
Output format
The output has N lines. Where line i starts with "Case i:" and then there should be exactly one space. Then the names of all the options used in the command line should be output in ascending alphabetical order. For the options with parameters, their parameters should be output after their names. If an option appears more than once on the command line, it is output only once. If an option with parameters appears more than once on the command line, only the parameters with the last occurrence are output.
sample input
albw:x
4
ls -a -l -a documents -b
ls
ls -w 10 -x -w 15
ls -a -b -c -d -e -l
sample output
Case 1: -a -l
Case 2:
Case 3: -w 15 -x
Case 4: -a -b
Solving problems
1. It is better to use c++11 regular for string processing,
2. The first input albw:x is analyzed and stored in a map, which is convenient for later searching and determining whether it has parameters
3. In order to facilitate processing, each output command line is first processed to remove the space, and then all substrings in the format of "- a15" are found out and stored using regular as the source of subsequent processing.
4. The questions should be output in ascending alphabetical order. Map can be used, and the key storage feature of map can be used
5. For regular use, please refer to several blogs on the Internet:
https://blog.csdn.net/qq_34802416/article/details/79307102
https://blog.csdn.net/A315776/article/details/104921039
Test code
#include<iostream> #include<stdlib.h> #include<regex> #include<vector> #include<string> #include<iterator> #include<map> #include<stdio.h> using namespace std; typedef map<char, int> map_i_c; typedef vector<map<char, string>> OUT; map_i_c rule_sub;//Decompose the rule. If int is 1, it means there are parameters. If int is 0, there are no parameters bool is_find(char m) { map_i_c::iterator itA; for (itA = begin(rule_sub); itA != end(rule_sub); ++itA) { if (itA->first == m) { return true; } } return false; } int main() { int num;//Number of records string rule; cin >> rule; cin >> num; //vector<string> str{ "ab:l","albw:x" ,"al::xw"}; vector<string> str; for (int i = 0; i < num+1; ++i) { string temp; getline(cin, temp); str.push_back(temp); } //Because the use of getline function causes more sring objects in str object than expected, move forward one bit and reset the size of STR for (int i = 1; i < str.size(); ++i) { str.at(i - 1) = str.at(i); } str.resize(num); regex ref( "([a-z]{1,}[:]{0,1}){1,}" ); if (regex_match(rule, ref)) {//Judge whether the rule input is reasonable for (string::iterator itA = rule.begin(); itA != rule.end();++itA) { if (*itA >= 'a'&&*itA <= 'z') { if (itA + 1 != rule.end()) {//Prevent cross-border if (*(itA + 1) == ':') { rule_sub[*itA] = 1; } else { rule_sub[*itA] = 0; } } else { rule_sub[*itA] = 0; } } } //Handle int count = 1; regex par{ " " }; for (string tmp : str) { #if 1 tmp = regex_replace(tmp, par, "");//Remove space for easy processing string::const_iterator itB = tmp.begin(); string::const_iterator itE = tmp.end(); smatch result; vector<string> res_fianl; map<char, string> out_sub; regex res{ "-[a-z]{1}[a-z0-9]*[\s]{0,1}" }; while (regex_search(itB, itE, result, res)) { res_fianl.push_back(result[0]);//result[0] stores matching results itB = result[0].second;///Update search start, search for remaining strings } //Handle for (string m : res_fianl) { //cout << m << endl; OUT out; if (is_find(m.at(1))) { if (rule_sub[m.at(1)] == 0) { if (m.size() == 2) {//Using map to achieve ascending output of letters out_sub[m.at(1)] = m; } } else if (rule_sub[m.at(1)] == 1) {//There are parameters. In two cases, there are correct parameters and there are no correct parameters if (m.size() > 3 && m.at(2) >= '0'&&m.at(2) <= '9') { string t; t += m.at(0); t += m.at(1); t += " "; for (string::iterator j = m.begin() + 2; j != m.end(); ++j) { t += *j; } out_sub[m.at(1)] = t; } //There are no correct parameters. Only those with correct parameters need not be processed } } } cout << "Case " << count << " :"; for (map<char, string>::iterator it = begin(out_sub); it != end(out_sub); ++it) { cout << " "<<it->second; } out_sub.clear();//Clear, easy to store next set of data cout << endl; count++; #endif } } system("pause"); return 0; }
Operation result
Question:
Why didn't the output in the sample of the original question - l? I tried my best. This question is too troublesome. I think it's probably too much for me.
Want to put it, two brushes are looking at it, welcome everyone to provide ideas