测试括号是否平衡,(a{[]b({})}c)[] returns false,但应该是 true

Testing if Parenthesis are balanced, (a{[]b({})}c)[] returns false, but should be true

这段代码的重点是测试每组字符串中的括号是否平衡。有 12 个测试必须全部通过,目前,我有 11 个在工作,但是最后一个不会工作。 目前,我有三个静态布尔值,用于阐明什么属于括号,以及它们是否匹配。

 private static bool IsOpeningParenthesis(char c)
        {
            return c == '(' || c == '[' || c == '{';
        }

private static bool IsClosingParenthesis(char c)
        {
            return c == ')' || c == ']' || c == '}';
        }

private static bool Matches(char a, char b)
        {
            return (a == '(' && b == ')') || (a == '[' && b == ']') ||
                (a == '{' && b == '}');
        }

下面,我有一个布尔值,它实际上检查它们是否匹配,这就是我的错误所在。

public static bool IsBalanced(string s)
        {
            Stack<char> myStack = new Stack<char>();

            foreach (char c in s)
            {
                if (IsOpeningParenthesis(c))
                {
                    myStack.Push(c);
                }
                if (IsClosingParenthesis(c))
                {
                    if (myStack.Count == 0) //takes care of closing parenthesis before adding char d
                    {
                        return false;
                    }
                    char d =  myStack.Pop();
                    if (c == d)
                    {
                        return true;
                    }
                    else
                    {
                        myStack.Push(d);
                        return false;
                    }   
                }
            }
            if(myStack.Count == 0)
            {
                return true;
            }
            else
            {
                return false;
            }

        }

最后一点代码,这些都是正在检查的测试。我目前正在努力处理测试编号 9 / TestFLongMatch。

public void TestFLongMatch()
        {
            Assert.That(ParenthesisMatcher.IsBalanced("(a{[]b({})}c)[]"), Is.True);
        }

下面是包含所有测试的完整文件

/* ParenthesisMatcherTests.cs
 * Author: Rod Howell
 */
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Ksu.Cis300.Parentheses;

namespace Ksu.Cis300.Parentheses.Tests
{
    /// <summary>
    /// A unit test class for the class library Ksu.Cis300.Parentheses.
    /// </summary>
    [TestFixture]
    public class ParenthesisMatcherTests
    {
        /// <summary>
        /// Checks the empty string, which is balanced.
        /// </summary>
        [Test, Timeout(1000)]
        public void TestAEmptyString()
        {
            Assert.That(ParenthesisMatcher.IsBalanced(""), Is.True);
        }

        /// <summary>
        /// Checks the string "abcdefg", which is balanced.
        /// </summary>
        [Test, Timeout(1000)]
        public void TestBNoParentheses()
        {
            Assert.That(ParenthesisMatcher.IsBalanced("abcdefg"), Is.True);
        }

        /// <summary>
        /// Checks the string "[", which is not balanced.
        /// </summary>
        [Test, Timeout(1000)]
        public void TestCOpeningParenthesis()
        {
            Assert.That(ParenthesisMatcher.IsBalanced("["), Is.False);
        }

        /// <summary>
        /// Checks the string ")", which is not balanced.
        /// </summary>
        [Test, Timeout(1000)]
        public void TestDClosingParenthesis()
        {
            Assert.That(ParenthesisMatcher.IsBalanced(")"), Is.False);
        }

        /// <summary>
        /// Tests the string "{{}", which is not balanced.
        /// </summary>
        [Test, Timeout(1000)]
        public void TestEMissingClose()
        {
            Assert.That(ParenthesisMatcher.IsBalanced("{{}"), Is.False);
        }

        /// <summary>
        /// Tests the string "[[]", which is not balanced.
        /// </summary>
        [Test, Timeout(1000)]
        public void TestEExtraClose()
        {
            Assert.That(ParenthesisMatcher.IsBalanced("[]]"), Is.False);
        }

        /// <summary>
        /// Tests the string "[}", which is not balanced.
        /// </summary>
        [Test, Timeout(1000)]
        public void TestEMismatch()
        {
            Assert.That(ParenthesisMatcher.IsBalanced("[}"), Is.False);
        }

        /// <summary>
        /// Tests the string "[}]", which is not balanced.
        /// </summary>
        [Test, Timeout(1000)]
        public void TestEMismatch2()
        {
            Assert.That(ParenthesisMatcher.IsBalanced("[}]"), Is.False);
        }

        /// <summary>
        /// Tests the string "(a{[]b({})}c)[]", which is balanced.
        /// </summary>
        [Test, Timeout(1000)]
        public void TestFLongMatch()
        {
            Assert.That(ParenthesisMatcher.IsBalanced("(a{[]b({})}c)[]"), Is.True);
        }

        /// <summary>
        /// Tests the string "(a{[]b({})}c)[](", whose last parenthesis is not matched.
        /// </summary>
        [Test, Timeout(1000)]
        public void TestFLongMissingClose()
        {
            Assert.That(ParenthesisMatcher.IsBalanced("(a{[]b({})}c)[]("), Is.False);
        }

        /// <summary>
        /// Tests the string "(a{[]b({})}c)[]())", whose last parenthesis is not matched.
        /// </summary>
        [Test, Timeout(1000)]
        public void TestFLongExtraClose()
        {
            Assert.That(ParenthesisMatcher.IsBalanced("(a{[]b({})}c)[]())"), Is.False);
        }

        /// <summary>
        /// Tests the string "(a{[]b({})}c}[]", whose first character is paired with the last '}', and
        /// hence is mismatched.
        /// </summary>
        [Test, Timeout(1000)]
        public void TestFLongMismatch()
        {
            Assert.That(ParenthesisMatcher.IsBalanced("(a{[]b({})}c}[]"), Is.False);
        }
    }
}

当我 运行 通过调试器进行特定测试时,代码将工作并且 运行 通过字符串直到到达第一个右括号。 一旦右括号开始起作用,左括号和右括号从测试中移除,程序就停止了 returning false。然而,它应该继续通过字符串和 return True。老实说,我迷失了这段代码,因为其他与这个非常相似的匹配字符串通过了,并且在第一个结束点后没有退出。

如有任何关于如何解决此问题的建议,我们将不胜感激。如果需要任何其他帮助,请告诉我,我尽量包含尽可能多的信息。

通过查看代码,我认为问题在于您的 IsBalanced 方法 returns false 在遇到右括号时立即执行。

在您的代码中,当遇到右括号时,这些是选项:

  1. 堆栈中没有项目:return false
  2. 堆栈中的第一项是相同的右括号(这是不可能的):return true
  3. return false

要解决此问题,您可能需要使用 Matches 方法来检查右括号是否与从堆栈中弹出的字符相匹配:

public static bool IsBalanced(string input)
{
    var stack = new Stack<char>();

    foreach (var chr in input)
    {
        if (IsOpeningParenthesis(chr))
        {
            stack.Push(chr);
        }
        else if (IsClosingParenthesis(chr))
        {
            if (stack.Count == 0) return false;
            if (!Matches(stack.Pop(), chr)) return false;
        }
    }

    return stack.Count == 0;
}