检查表达式 C# 中的平衡括号

Posted

技术标签:

【中文标题】检查表达式 C# 中的平衡括号【英文标题】:Check for balanced parentheses in an expression C# 【发布时间】:2020-10-14 00:06:39 【问题描述】:

希望你做得很好。我一直在努力处理这段代码。我认为这必须有效,但我无法准确地看到我有错误的问题(我就像盲人)。 你能帮忙吗....提前谢谢。 两个字符串都返回 FALSE。但首先必须是 TRUE。

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class PatternFinder : MonoBehaviour

    public void Check()
    
        String test_good = "()()()";//this must return TRUE
        String test_bad = "((())()";//this must return FALSE

        Debug.Log(checkBalanced(test_good));
        Debug.Log(checkBalanced(test_bad));
    

    public static bool checkBalanced(String check)
    
        Stack<char> stack = new Stack<char>();
        for (int i = 0; i < check.Length; i++)
        
            char character = check[i];
            if (character == '[' || character == '' || character == '(')
                stack.Push(character);
            else if (character == ']' || character == '' || character == ')')
            
                if (stack.Any())
                    return false;
                switch (character)
                
                    case ']':
                        if (stack.Pop() != '[')
                            return false;
                        break;
                    case '':
                        if (stack.Pop() != '')
                            return false;
                        break;
                    case ')':
                        if (stack.Pop() != '(')
                            return false;
                        break;
                    default:
                        break;
                
            
        
        if (stack.Any())
            return true;
        return false;
    

【问题讨论】:

if (stack.Any()) return false; 看起来很可疑。如果遇到),而之前有(,为什么会说表达式不平衡? 另外,学习如何自己调试代码而不是让我们来调试可能对您更有用。这是一篇关于该主题的热门博文:ericlippert.com/2014/03/05/how-to-debug-small-programs>. 【参考方案1】:
string str = "((())";
            Stack<char> lefts=new Stack<char>();
            Stack<char> rights = new Stack<char>();
            char[] ar = str.ToArray();
            int countl = 0;
            for(int i =0; i<ar.Length;++i)
            
                if (ar[i] == '(')
                    lefts.Push(ar[i]);
                if (ar[i] == ')')
                    rights.Push(ar[i]);
              
            
            str = "";
            Stack<char> f = new Stack<char>();
            if(lefts.Count==rights.Count)
            
                countl = lefts.Count;
                for (int i = 0; i < countl; ++i)
                    f.Push(rights.Pop());
                for (int i = 0; i < countl; ++i)
                    f.Push(lefts.Pop());
                for (int i = 0; i < countl*2; ++i)
                    str += f.Pop();
            
            if (lefts.Count > rights.Count)
            
                countl = lefts.Count;
                for (int i = 0; i < countl; ++i)
                
                    f.Push(rights.Count > 0 ? rights.Pop() : ')');
                
                for (int i = 0; i < countl; ++i)
                
                    f.Push(lefts.Pop());
                
                   
                for (int i = 0; i < countl * 2; ++i)
                    str += f.Pop();
            
            if (lefts.Count < rights.Count)
            
                countl = rights.Count;
                for (int i = 0; i < countl; ++i)
                
                    f.Push(rights.Pop());
                
                for (int i = 0; i < countl; ++i)
                
                    f.Push(lefts.Count > 0 ? lefts.Pop() : '(');
                
                
                for (int i = 0; i < countl * 2; ++i)
                    str += f.Pop();
            

            Console.WriteLine(str);

【讨论】:

【参考方案2】:

试试这个

 public static List<char[]> TOKENS = new List<char[]>
        
            new char[]  '(', ')' , new char[] '', '' ,new char[]  '[', ']' 
        ;

        static bool IsBalance(string str)
        
            if (string.IsNullOrEmpty(str))
                return false;

            Stack<char> stack = new();

            foreach (var item in str.ToCharArray())
            
                if (IsOpenToken(item))
                
                    stack.Push(item);
                
                else if (IsMatch(item, stack.Peek()))
                
                    if (stack.Count > 0)
                    
                        stack.Pop();
                    
                    else
                    
                        return false;
                    
                
            

            if (stack.Count == 0)
                return true;

            return false;
        

        private static bool IsOpenToken(char term)
        
            foreach (var item in TOKENS)
            
                if (item[0] == term)
                
                    return true;
                
            

            return false;
        

        private static bool IsMatch(char closeTrim, char openTrim)
        
            foreach (var item in TOKENS)
            
                if (item[0] == openTrim)
                
                    return item[1] == closeTrim;
                
            

            return false;
        



        static void Main(string[] args)
        
            Console.WriteLine(IsBalance("[()]"));
            Console.WriteLine();
            Console.WriteLine(IsBalance("([])"));
            Console.WriteLine();
            Console.WriteLine(IsBalance("()()()"));
            Console.WriteLine();
            Console.WriteLine(IsBalance("((())"));
        

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。【参考方案3】:
static bool Balanced_Or_Not(Stack<char> EXP)
        
            bool result = true; 
            List<char> Open = EXP.Where(ch => ch == '' || ch == '[' || ch == '(').ToList();
            List<char> Closed = EXP.Where(ch => ch == '' || ch == ']' || ch == ')').ToList();
            Closed.Reverse();
            if (Open.Count() == Closed.Count())
            
                int counter = 0;
                foreach (var item in Open)
                
                    result = (item == '(' && Closed[counter] == ')') || (item == '' && Closed[counter] == '') || (item == '[' && Closed[counter] == ']') ? true : false;
                    counter++;
                    if (!result)
                    
                        break;
                    
                
            
            else result = false; 
            return result; 
        

【讨论】:

欢迎来到 ***!请解释您的解决方案。【参考方案4】:

您不希望在输入此 if 语句后立即使用 stack.Any()。它会导致您过早地从函数中返回。因为如果堆栈中有任何东西,它就存在该函数而不删除任何东西。

        else if (character == ']' || character == '' || character == ')')
        
            if (stack.Any()) // you don't want this here
                return false; 

在从堆栈中弹出任何内容之前拥有 stack.Any() 并不能起到任何作用,因为您想遍历字符串直到找到不匹配的字符串。

相反,您应该使用 !stack.Any(),因为如果堆栈为空并且您有一个结束字符,则它是不平衡的。

public static bool checkBalanced(String check)

    Stack<char> stack = new Stack<char>();
    for (int i = 0; i < check.Length; i++)
    
        char character = check[i];
        if (character == '[' || character == '' || character == '(')
            stack.Push(character);
        else if (character == ']' || character == '' || character == ')')
        
            if (!stack.Any()) // if stack is empty and you have a closing character this means that it is unbalanced 
                return false;
            switch (character)
            
                case ']':
                    if (stack.Pop() != '[')
                        return false;
                    break;
                case '':
                    if (stack.Pop() != '')
                        return false;
                    break;
                case ')':
                    if (stack.Pop() != '(')
                        return false;
                    break;
                default:
                    break;
            
        
    
    // it is balanced only if there aren't any left
    if (!stack.Any())
        return true;
    return false;

【讨论】:

但是如果堆栈上没有项目并且它会检查该行,那么该行将是有意义的。 if(!stack.Any()) 会很好。 @mlibby 不,您想在决定是否平衡之前检查整个字符串。 @mlibby 相反,如果堆栈为空,您想要继续循环的下一次迭代。 在原始堆栈中只有 [、 或 (,因此如果您找到字符 ]、 或 ) 并且堆栈为空,则表示不平衡。 @mlibby 谢谢,我更正了我的答案。 stack.Any() 都应该是 !stack.Any()

以上是关于检查表达式 C# 中的平衡括号的主要内容,如果未能解决你的问题,请参考以下文章

如何纠正正则表达式中的不平衡括号错误?

如何获得平衡括号之间的表达式

在c#请用Stack来检查程序的语句或公式是不是括号匹配

在javascript中,我需要一个正则表达式来匹配电话号码中的平衡括号 /^([1]0,1)\s?\(?\d3\)?[-\s]?\d 3[-\s]?\d4$/

正则表达式平衡括号

c#用正则表达式提取小括号中的内容