如何在 c++ 中将字符串拆分为左括号和右括号之间的字符串列表?

Posted

技术标签:

【中文标题】如何在 c++ 中将字符串拆分为左括号和右括号之间的字符串列表?【英文标题】:How do I split a string into a list of strings between opening and closing parentheses in 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() 逐个字符遍历字符串并计算左括号和右括号。然而,这变得非常棘手,我不相信这是最有效或最简单的方法。任何想法将不胜感激!

【问题讨论】:

这可以很容易地递归完成。只需遍历您的字符串,如果您点击了(,则递归以从您找到( 的位置解析子字符串。如果你点击),你已经找到了一个子字符串的结尾并且可以返回开始和结束…… 你能提供一个Minimal, Verifiable, and Complete Example? 【参考方案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::stringstart, ++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::stringstart, ++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

以上是关于如何在 c++ 中将字符串拆分为左括号和右括号之间的字符串列表?的主要内容,如果未能解决你的问题,请参考以下文章

目标 C:在括号之间拆分文本

正则表达式拆分字符串,提取之前的字符串值和方括号之间的数值

你如何在 C++ 中拆分数组?

C# Regex.Split,如何将字符串拆分为用括号括起来而不是用括号括起来?

如果搜索字符串包含左“(”和右“)”括号,NSPredicate 不起作用

正则表达式匹配对称小括号