题目的主要信息:

  • 输入一行命令,命令参数之间按照空格分开,需输出命令单独的各个参数
  • 引号包含的参数中间有空格,不用解析为多个参数,只解析引号之间的
  • 引号不会嵌套
  • 输出不能包含引号
  • 参数不定长
  • 进阶要求:时间复杂度O(n)O(n),空间复杂度O(n)O(n)

方法一:字符连接

具体做法:

我们可以准备一个临时字符串,记录解析出来的参数,用一个bool型变量表示是否在引号中,一开始不在。遍历命令行,如果是在引号中,遇到的非引号字符都加到临时字符串后面,遇到引号就设置bool变量为出了引号;如果不在引号中,遇到空格就将临时字符串中的内容加入数组,然后情况该字符串,后面继续添加,遇到引号则设置bool变量为进入引号,其他照常加到临时字符串末尾。

最后需要将最后一个参数的临时字符串加入数组,然后输出数组的长度和各个元素。

#include<iostream>
#include<string>
#include<vector>
using namespace std;

int main(){
    string s;
    while(getline(cin, s)){
        vector<string> output;
        string temp = "";
        bool flag = false; //记录是否进入引号中
        for(int i = 0; i < s.length(); i++){
            if(flag){ //如果在引号中
                if(s[i] != '\"') //遇到非引号都添加为字符串
                    temp += s[i];
                else flag = false; //否则设置出引号
            }else{ //如果不在引号中
                if(s[i] == ' '){ //遇到空格隔断
                    output.push_back(temp); 
                    temp = "";
                }else if(s[i] == '\"') //遇到引号设置为进入引号
                    flag = true; 
                else //其余添加进字符串
                    temp += s[i];
            }
        }
        output.push_back(temp); //最后一段
        cout << output.size() << endl; //输出参数个数
        for(int i = 0; i < output.size(); i++)
            cout << output[i] << endl;
    }
    return 0;
}

复杂度分析:

  • 时间复杂度:O(n)O(n),其中nn为输入的字符串长度,遍历整个输入的字符串
  • 空间复杂度:O(n)O(n),临时字符串长度最坏为nn

方法二:字符串截取

具体做法:

除了拼接成字符,我们还可以采取字符串截取的方法,就不使用临时字符串变量了,但还是需要记录是否在引号中。

首先,如果遇到引号,要判断是否在引号中,如果不在,则是第一个引号,如果在则是第二个引号,第二个引号就将这串字符串开始到引号前的子串加入数组,然后新的子串开始位置从引号后一个位置开始。

如果遇到空格且不在引号中的情况,需要将子串截取加入数组,但是要提前判断是否是空子串(引号和空格相连的时候就会出现空子串)。

最后需要判断是否是字符串最后一个位置,要将最后一个参数字符串加入。

alt

#include<iostream>
#include<string>
#include<vector>
using namespace std;

int main(){
    string s;
    while(getline(cin, s)){
        vector<string> output;
        int p = 0;
        bool flag = false; //记录是否进入引号中
        for(int i = 0; i < s.length(); i++){
            if(s[i] == '\"'){ //遇到引号
                if(!flag) //第一个引号
                    flag = true;
                else{ //第二个引号
                    flag = false;
                    output.push_back(s.substr(p, i - p)); //截取字符串加入
                }
                p = i + 1;
            } else if(s[i] == ' ' && !flag){ //遇到引号外的空格
                if(i != p)  //非空字符串
                    output.push_back(s.substr(p, i - p)); //截取字符串加入
                p = i + 1;
            } else if(i == s.length() - 1) //最后一个参数字符串
                output.push_back(s.substr(p, i - p + 1));
        }
        cout << output.size() << endl; //输出参数个数
        for(int i = 0; i < output.size(); i++)
            cout << output[i] << endl;
    }
    return 0;
}

复杂度分析:

  • 时间复杂度:O(n)O(n),其中nn为输入的字符串长度,遍历整个输入的字符串
  • 空间复杂度:O(n)O(n),记录输出的字符串数组的大小为输入字符串的长度