如何通过多种括号类型拆分字符串,但仍将括号保留在C ++中?

时间:2018-09-26 19:04:11

标签: c++ string vector data-structures split

有没有一种方法可以将字符串分成小部分并存储为向量。

例如:

字符串:str = "(a b c) d e f [[g h i]]"。预期的输出是:

(a b c)
d e f
[[g h i]]

示例代码:

vector<string> token;
string str = "(a b c)d e f[[g h i]]";
string bracketS = "()[]";
istringstream ss(str);
string section;
string tok;

while (getline(ss,section)) {
    size_t start = 0;
    size_t end = section.find_first_of(bracketS);
    while (end != string::npos) {
        tok = section.substr(start, end - start);
        token.push_back(tok);
        start = end + 1;
        end = section.find_first_of(bracketS, start);
    }
}

输出没有括号:

      a b c
      d e f
      g h i 

试图调整我的section.substr(start-1, end - start+2) 然后我的输出是:

(a b c)
) d e f [
[g h i]

为什么中间向量是错误的。

也尝试做strtok。但是输出与第一个相同。

还有其他方法吗?

1 个答案:

答案 0 :(得分:1)

这是一种可能的解决方案,其中有一个堆栈用于在缺少左括号或右括号与开头不匹配的情况下解析并引发parsing_error。

#include <iostream>
#include <stack>
#include <string>
#include <vector>

const auto Brackets = { std::make_pair('(', ')'), std::make_pair('[', ']') };

const auto is_opening_bracket = [](const char c) {
    return std::find_if(Brackets.begin(), Brackets.end(),
            [c](const auto& p) { return p.first == c; } ) != Brackets.end();
};
const auto is_closing_bracket = [](const char c) {
    return std::find_if(Brackets.begin(), Brackets.end(),
            [c](const auto& p) { return p.second == c; } ) != Brackets.end();
};

const auto get_opening_bracket = [](const char c) {
    const auto p = std::find_if(Brackets.begin(), Brackets.end(), [c](const auto& p) { return p.second == c; });
    if (p == Brackets.end())
        return '0';

    return p->first;
};

struct parsing_error {};

int main() {
    const std::string str = "(a b c)d e f[[g h i]]";

    std::stack<char> brackets;
    std::vector<std::string> tokens;
    std::string token;

    for (const auto c : str) {
        if (is_opening_bracket(c)) {
            if (!token.empty() && brackets.empty()) {
                tokens.push_back(token);
                token.clear();
            }

            brackets.push(c);
            token += c;
        } else if (is_closing_bracket(c)) {
            if (brackets.top() != get_opening_bracket(c))
                throw parsing_error();

            brackets.pop();
            token += c;

            if (brackets.empty()) {
                tokens.push_back(token);
                token.clear();
            }
        } else {
            token += c;
        }

    }

    if (!brackets.empty())
        throw parsing_error();

    for (const auto& token : tokens)
        std::cout << token << '\n';

    return 0;
}