【问题标题】:How do I split a string into a list of strings between opening and closing parentheses in c++?如何在 c++ 中将字符串拆分为左括号和右括号之间的字符串列表?
【发布时间】:2019-04-21 17:49:55
【问题描述】:

我需要一些关于如何将字符串解析为多个子字符串的方法的帮助。字符串的形式可能是 (if (a = b) (a) (b)) 或类似的形式,带有许多左括号和右括号。例如,我需要一个字符串列表,例如

元素(0)=“(如果(a = b)(a)(b))”

元素(1) = "(a = b)",

元素(2)=“(a)”,和

元素(3)=“(b)”。

我已经尝试使用 String.at() 逐个字符遍历字符串并计算左括号和右括号。然而,这变得非常棘手,我不相信这是最有效或最简单的方法。任何想法将不胜感激!

【问题讨论】:

  • 这可以很容易地递归完成。只需遍历您的字符串,如果您点击了(,则递归以从您找到( 的位置解析子字符串。如果你点击),你已经找到了一个子字符串的结尾并且可以返回开始和结束……

标签: c++ string substring


【解决方案1】:

你可以从简单的堆栈算法开始:

#include <iostream>
#include <stack>
#include <string>
#include <deque>

std::deque<std::string> parse(const std::string &str)
{
    std::deque<std::string> result;
    std::stack<std::string::const_iterator> stack;
    for ( auto it = str.begin(); it != str.end();) {
        if (*it == '(') {
            stack.push(it++);
        } else if (*it == ')') {
            auto start = stack.top(); stack.pop();
            result.push_back(std::string{start, ++it});
        } else {
            it++;
        }
    }
    return result;
}

int main(int , char **) {
    std::string input = "(if (a = b) (a) (b))";
    auto output = parse(input);
    for(const  auto & s:output) {
        std::cout << s << " ";
    }
    std::cout <<std::endl;
    return 0;
}

不要忘记添加检查堆栈是否下溢

或者,如果您想保留有问题的确切顺序,请使用std::map&lt;std::size_t, std::deque&lt;std::string&gt;&gt;

#include <iostream>
#include <stack>
#include <string>
#include <deque>
#include <map>

std::deque<std::string> parse(const std::string &str)
{
    std::map<std::size_t, std::deque<std::string>> map;
    std::stack<std::string::const_iterator> stack;
    for ( auto it = str.begin(); it != str.end();) {
        if (*it == '(') {
            stack.push(it++);
        } else if (*it == ')') {
            auto start = stack.top(); stack.pop();
            map[stack.size()].push_back(std::string{start, ++it});
        } else {
            it++;
        }
    }
    std::deque<std::string> result;
    for (const auto & p : map) {
        for (const auto & s : p.second) {
            result.push_back(s);
        }
    }
    return result;
}

int main(int , char **) {
    std::string input = "(if (a = b) (a) (b))";
    auto output = parse(input);
    for(const  auto & s:output) {
        std::cout << s << " ";
    }
    std::cout <<std::endl;
    return 0;
}

【讨论】:

  • 哇,谢谢!这完美地回答了我的问题,也澄清了一些关于 C++ 的问题。这是我第一次使用 C++,而不是 C、Java 或 Swift。所以谢谢你的帮助!
  • @Lucas 你也可以在这里查看来源github.com/kelebdil/study/blob/master/brackets/main.cpp
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-12
  • 1970-01-01
  • 2017-08-24
  • 1970-01-01
  • 2020-09-19
  • 1970-01-01
  • 2017-03-12
相关资源
最近更新 更多