Finding all combinations of well-formed brackets

后端 未结 29 1506
盖世英雄少女心
盖世英雄少女心 2020-11-28 02:34

This came up while talking to a friend and I thought I\'d ask here since it\'s an interesting problem and would like to see other people\'s solutions.

The task is to

相关标签:
29条回答
  • 2020-11-28 03:01

    Not the most elegant solution, but this was how I did it in C++ (Visual Studio 2008). Leveraging the STL set to eliminate duplicates, I just naively insert new () pairs into each string index in every string from the previous generation, then recurse.

    #include "stdafx.h"
    #include <iostream>
    #include <string>
    #include <set>
    
    using namespace System;
    using namespace std;
    
    typedef set<string> StrSet;
    
    void ExpandSet( StrSet &Results, int Curr, int Max )
    {
        if (Curr < Max)
        {
            StrSet NewResults;
    
            for (StrSet::iterator it = Results.begin(); it != Results.end(); ++it)
            {
                for (unsigned int stri=0; stri < (*it).length(); stri++)
                {
                    string NewStr( *it );
                    NewResults.insert( NewStr.insert( stri, string("()") ) );
                }
            }
            ExpandSet( NewResults, Curr+1, Max );
    
            Results = NewResults;
        }
    }    
    
    int main(array<System::String ^> ^args)
    {
        int ParenCount = 0;
    
        cout << "Enter the parens to balance:" << endl;
        cin  >> ParenCount;
    
        StrSet Results;
        Results.insert( string("()") );
    
        ExpandSet(Results, 1, ParenCount);
    
        cout << Results.size() << ": Total # of results for " << ParenCount << " parens:" << endl;
    
        for (StrSet::iterator it = Results.begin(); it != Results.end(); ++it)
        {
            cout << *it << endl;
        }
    
    
        return 0;
    }
    
    0 讨论(0)
  • 2020-11-28 03:01
    public static void printAllValidBracePermutations(int size) {
        printAllValidBracePermutations_internal("", 0, 2 * size);
    }
    
    private static void printAllValidBracePermutations_internal(String str, int bal, int len) {
        if (len == 0) System.out.println(str);
        else if (len > 0) {
            if (bal <= len / 2) printAllValidBracePermutations_internal(str + "{", bal + 1, len - 1);
            if (bal > 0) printAllValidBracePermutations_internal(str + "}", bal - 1, len - 1);
        }
    }
    
    0 讨论(0)
  • 2020-11-28 03:03
    def @memo brackets ( n )
        => [] if n == 0 else around( n ) ++ pre( n ) ++ post( n ) ++ [ "()" * n) ]
    
    def @memo pre ( n )
        => map ( ( s ) => "()" ++ s, pre ( n - 1 ) ++ around ( n - 1 ) ) if n > 2 else []
    
    def @memo post ( n )
        => map ( ( s ) => s ++ "()", post ( n - 1 ) ++ around ( n - 1 ) ) if n > 2 else []
    
    def @memo around ( n )
        => map ( ( s ) => "(" ++ s ++ ")", brackets( n - 1 ) )
    

    (kin, which is something like an actor model based linear python with traits. I haven't got round to implementing @memo but the above works without that optimisation)

    0 讨论(0)
  • 2020-11-28 03:03

    Provider C# version based on recursive backtracking algorithm, hope it's helpful.

    public List<String> generateParenthesis(int n) {
       List<String> result = new LinkedList<String>();
       Generate("", 0, 0, n, result);
       return result;
    }
    
    private void Generate(String s, int l, int r, int n, List<String> result){
       if(l == n && r == n){
           result.add(s);
           return;
       }
    
       if(l<n){
           Generate(s+"(", l+1, r, n, result);    
       }
    
       if(r < l)
           Generate(s+")", l , r+1, n, result);
     }}
    
    0 讨论(0)
  • 2020-11-28 03:05

    Common Lisp:

    This doesn't print them, but does produce a list of lists of all the possible structures. My method is a bit different from the others'. It restructures the solutions to brackets(n - 1) such that they become brackets(n). My solution isn't tail recursive, but it could be made so with a little work.

    Code

    (defun brackets (n)
      (if (= 1 n)
          '((()))
          (loop for el in (brackets (1- n))
                when (cdr el)
                collect (cons (list (car el)) (cdr el))
                collect (list el)
                collect (cons '() el))))
    
    0 讨论(0)
  • 2020-11-28 03:05

    Here is a solution in C++. The main idea that I use is that I take the output from the previous i (where i is the number of bracket pairs), and feed that as input to the next i. Then, for each string in the input, we put a bracket pair at each location in the string. New strings are added to a set in order to eliminate duplicates.

    #include <iostream>
    #include <set>
    using namespace std;
    void brackets( int n );
    void brackets_aux( int x, const set<string>& input_set, set<string>& output_set );
    
    int main() {
        int n;
        cout << "Enter n: ";
        cin >> n;
        brackets(n);
        return 0;
    }
    
    void brackets( int n ) {
        set<string>* set1 = new set<string>;
        set<string>* set2;
    
        for( int i = 1; i <= n; i++ ) {
            set2 = new set<string>;
            brackets_aux( i, *set1, *set2 );
            delete set1;
            set1 = set2;
        }
    }
    
    void brackets_aux( int x, const set<string>& input_set, set<string>& output_set ) {
        // Build set of bracket strings to print
        if( x == 1 ) {
            output_set.insert( "()" );
        }
        else {
            // For each input string, generate the output strings when inserting a bracket pair
            for( set<string>::iterator s = input_set.begin(); s != input_set.end(); s++ ) {
                // For each location in the string, insert bracket pair before location if valid
                for( unsigned int i = 0; i < s->size(); i++ ) {
                    string s2 = *s;
                    s2.insert( i, "()" );
                    output_set.insert( s2 );
                }
                output_set.insert( *s + "()" );
            }
        }
    
        // Print them
        for( set<string>::iterator i = output_set.begin(); i != output_set.end(); i++ ) {
            cout << *i << "  ";
        }
        cout << endl;
    }
    
    0 讨论(0)
提交回复
热议问题