【问题标题】:How to check if braces are closed and in the right order? [duplicate]如何检查大括号是否闭合且顺序正确? [复制]
【发布时间】:2017-05-17 20:23:31
【问题描述】:

我今天试图解决一个挑战,但我做不到。我必须确保字符串的所有大括号都闭合且顺序正确。

例如,这些是正确的:

{[()]}
{}()[]
{((()))}[]

这些不会:

{[}]
{{)}

我想用正则表达式做,我做不到,谁能告诉我怎么做? (正则表达式或其他方式)。

澄清一下,我不是想获取大括号内的内容,里面没有任何内容。

【问题讨论】:

  • 显示您尝试解决的问题
  • 读得好-stackoverflow.com/questions/1732348/…(您应该清楚地阅读所有答案,以了解为什么通常使用正则表达式无法解析嵌套结构,但为了节省您一些时间-stackoverflow.com/a/7564061/477420 为您提供了一个选项,如果你可以使用 .Net 的正则表达式)
  • 一次遍历一个字符 - 将左大括号推入堆栈,对于右大括号,将顶部字符弹出堆栈并确保它们匹配。
  • 您尝试在哪种语言中使用正则表达式?引擎在功能/语法上有所不同。
  • @Alex,在定时环境中这是一个挑战,我没有保留代码。

标签: regex algorithm


【解决方案1】:

这可以使用 LIFO stack 一次性通过字符串来解决。循环遍历字符串,并在每个字符处执行以下操作:

  • 如果当前字符是“左”大括号,则将其添加到堆栈中。
  • 如果当前字符是“右”大括号,则从堆栈中弹出顶部字符并进行比较。
    • 如果您刚刚找到的“右”大括号与堆栈中的“左”大括号类型相同,则这两个大括号正确匹配。继续。
    • 如果您刚刚找到的“右”大括号与堆栈中的“左”大括号匹配,则您的大括号乱序。返回 false。
    • 如果堆栈在您尝试弹出时为空,则说明您有太多的尾括号。返回 false。

一旦你到达字符串的末尾,只需检查堆栈上的元素数量。

  • 如果堆栈中有任何内容,则说明前大括号过多。返回 false。
  • 如果堆栈为空,则您的大括号是平衡的。返回真。

C# 中的示例实现(无非大括号字符的错误处理):

public static bool IsMatched(string braces)
{
    const string openBraces = "([{";
    const string closeBraces = ")]}";

    Stack<char> stack = new Stack<char>();
    foreach (char c in braces)
    {
        if (openBraces.Contains(c))
        {
            stack.Push(c);
        }
        else if (stack.Count == 0 || openBraces.IndexOf(stack.Pop()) != closeBraces.IndexOf(c))
        {
            return false;
        }
    }
    return stack.Count == 0;
}

【讨论】:

    【解决方案2】:

    问题可以通过正则表达式解决,但不是最快的解决方案。只需删除所有[]{}(),直到字符串不再收缩。如果它的长度为 0,则表达式是正确的(下面的正则表达式还允许空格):

    document.body.innerHTML = parse('{((()))}[]');
    
    function parse(s) {
        let t;
        do {
            t = s;
            s = s.replace(/ *(\{ *\}|\( *\)|\[ *\]) */g, "");
        } while (t.length != s.length);
        return s.length == 0;
    }
    

    【讨论】:

    • 感谢您回答这个问题。引用一个方便的小函数。
    • 但是当我在错误的地方有一个大括号关闭时,这不会“覆盖”,例如,{[ }] 这是无效的,因为关闭 ] 在 { } 之外。
    • @GabrielReis 它将起作用,因为仅删除了 {}[] 而未删除 {]}[}],因此该字符串不会被正则表达式缩短并立即返回 false。
    • 这里的正则表达式主要是为了迷惑人们:s = s.replace("{}","").replace("()","").replace("[]","") 会更容易阅读/解释这种方法......所以不是真正的正则表达式解决方案 - 所以可能是重复的。
    • @AlexeiLevenkov 除了这个解决方案会更糟,因为它从一开始就开始查找每次替换并且每次只替换一次。如果你想简化:s = s.replace(/\{\}|\[\]|\(\)/g, "");
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-15
    • 2021-11-25
    • 2022-08-13
    • 2019-11-01
    • 2014-12-25
    • 1970-01-01
    相关资源
    最近更新 更多