【算法】找出平衡括号的排列组合

用c#编写一个函数,列出一个字符串列表,此字符串表示平衡n对括号的所有方法的排列组合。

示例:
BalancedParens(0) returns List<string> with element: ""
BalancedParens(1) returns List<string> with element: "()"
BalancedParens(2) returns List<string> with elements: "()()","(())"
BalancedParens(3) returns List<string> with elements: "()()()","(())()","()(())","(()())","((()))"


这个算法使用递归的方法生成所有可能的平衡括号组合:

1. 创建一个空的字符串列表 `result`,用于存储生成的括号组合。
2. 调用 `GenerateParens` 方法,传入初始参数 `result`、空字符串 `""`、括号对数 `n` 和 `n`。
3. 在 `GenerateParens` 方法中进行以下操作:
- 基本情况:如果没有剩余的开括号和闭括号,即 `open` 和 `close` 都等于 0,则将当前字符串 `current` 添加到 `result` 列表中,并返回。
- 如果还有剩余的开括号,即 `open` 大于 0,则将一个开括号添加到 `current` 字符串中,并递归调用 `GenerateParens` 方法,将 `open` 减 1。
- 如果剩余的闭括号数量大于剩余的开括号数量,即 `close` 大于 `open`,则将一个闭括号添加到 `current` 字符串中,并递归调用 `GenerateParens` 方法,将 `close` 减 1。
4. 在 `Main` 方法中进行以下操作:
- 调用 `BalancedParens` 方法,传入括号对数作为参数,获取生成的括号组合列表。
- 使用 `string.Join` 方法将列表中的元素以逗号分隔并打印输出。

using System;
using System.Collections.Generic;

public class Program
{
    public static List<string> BalancedParens(int n)
    {
        List<string> result = new List<string>();
        GenerateParens(result, "", n, n);
        return result;
    }

    private static void GenerateParens(List<string> result, string current, int open, int close)
    {
        // Base case: All parentheses have been used
        if (open == 0 && close == 0)
        {
            result.Add(current);
            return;
        }

        // If there are still open parentheses remaining, add an opening parenthesis
        if (open > 0)
        {
            GenerateParens(result, current + "(", open - 1, close);
        }

        // If there are more closed parentheses than open parentheses, add a closing parenthesis
        if (close > open)
        {
            GenerateParens(result, current + ")", open, close - 1);
        }
    }

}

测试用例:

TestParens 方法是一个辅助方法,用于生成预期的括号组合列表。它使用了深度优先搜索(DFS)的思想,通过递归地添加开括号和闭括号来生成所有可能的组合。生成的组合被添加到列表 lst 中,并最终返回。

测试用例的设计思路是:根据不同的括号对数,生成预期的括号组合列表,然后调用 BalancedParens 方法生成的括号组合列表,并使用断言来验证两者是否相等。这样,我们可以确保算法在不同输入情况下都能正确生成平衡的括号组合。同时,通过对输入的括号对数进行随机化处理,可以增加测试的覆盖范围,提高测试的可靠性。

using NUnit.Framework;
using System;
using System.Text;
using System.Collections.Generic;
public class SolutionTest
{
    [Test]
    public void TestCases()
    {
        var warriorResult = new List<string>();
        var testList = new List<string>();
        var testValues = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
        Shuffle(testValues);
        foreach (int target in testValues)
        {
            testList = TestParens(target);
            testList.Sort();
            warriorResult = Balanced.BalancedParens(target);
            warriorResult.Sort();
            Assert.AreEqual(testList, warriorResult);
            Console.WriteLine("Value of n = " + target);
        }
    }

    private static void Shuffle<T>(List<T> deck)
    {
        var rnd = new Random();
        for (int n = deck.Count - 1; n > 0; --n)
        {
            int k = rnd.Next(n + 1);
            T temp = deck[n];
            deck[n] = deck[k];
            deck[k] = temp;
        }
    }

    private static List<string> TestParens(int n)
    {
        var lst = new List<string>();
        var sb = new StringBuilder();
        Dfs(sb, lst, 0, 0, n);
        return lst;
    }
    private static void Dfs(StringBuilder sb, List<string> lst, int open, int close, int max)
    {
        if (close == max)
        {
            lst.Add(sb.ToString());
            return;
        }
        if (open > close)
        {
            sb.Append(')');
            Dfs(sb, lst, open, close + 1, max);
            sb.Remove(sb.Length - 1, 1);
        }
        if (open < max)
        {
            sb.Append('(');
            Dfs(sb, lst, open + 1, close, max);
            sb.Remove(sb.Length - 1, 1);
        }
    }
}

 

posted @ 2023-07-03 08:13  lanedm  阅读(67)  评论(0编辑  收藏  举报