【问题标题】:How to split string by multiple bracket types but still keep the brackets in C++?如何按多种括号类型拆分字符串但仍将括号保留在 C++ 中?
【发布时间】:2019-03-02 15:08:57
【问题描述】:

有没有办法将字符串分成小部分并存储到向量中。

例如:

一个字符串: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。但是输出和第一个一样。

还有其他方法吗?

【问题讨论】:

  • 简单地使用std::regex怎么样?
  • 如果您对正则表达式一无所知,但对基本数据结构有一点了解,您可以尝试std::stack 并知道何时可以使用 topushpop,然后不需要strtok。您尝试使用“蛮力”解析是一种天真的方法。
  • @PaulMcKenzie 谢天谢地,OP 根本没有在他们的代码中使用 strtok(),还是我错过了什么?
  • @πάνταῥεῖ OP 在他的帖子中提到了strtok
  • 不清楚你想用嵌套括号做什么。例如,(a b c) (d [e f] g) 的结果是什么?

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


【解决方案1】:

如果有左括号缺少右括号或右括号与左括号不匹配,这是一种可能的解决方案,使用堆栈进行解析并引发 parseing_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;
}

【讨论】:

  • 这是一个很好的努力,但是当答案发布时,关于解决方案如何工作的一些背景知识(算法概要,进一步阅读的链接等)比仅仅发布代码更好.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-21
  • 2012-10-26
  • 2018-04-14
  • 2020-09-20
相关资源
最近更新 更多