Как разбить строку на несколько типов скобок, но при этом сохранить скобки в C ++? - PullRequest
0 голосов
/ 26 сентября 2018

Есть ли способ разбить строку на небольшую часть и сохранить в векторе.

Например:

Строка: 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 голосов
/ 26 сентября 2018

Это возможное решение со стеком для разбора и выдачи ошибки 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;
}
...