Basic Recursion, Check Balanced Parenthesis

前端 未结 12 1145
孤独总比滥情好
孤独总比滥情好 2020-11-29 17:56

I\'ve written software in the past that uses a stack to check for balanced equations, but now I\'m asked to write a similar algorithm recursively to check for properly neste

相关标签:
12条回答
  • 2020-11-29 18:18

    First, to your original question, just be aware that if you're working with very long strings, you don't want to be making exact copies minus a single letter each time you make a function call. So you should favor using indexes or verify that your language of choice isn't making copies behind the scenes.

    Second, I have an issue with all the answers here that are using a stack data structure. I think the point of your assignment is for you to understand that with recursion your function calls create a stack. You don't need to use a stack data structure to hold your parentheses because each recursive call is a new entry on an implicit stack.

    I'll demonstrate with a C program that matches ( and ). Adding the other types like [ and ] is an exercise for the reader. All I maintain in the function is my position in the string (passed as a pointer) because the recursion is my stack.

    /* Search a string for matching parentheses.  If the parentheses match, returns a
     * pointer that addresses the nul terminator at the end of the string.  If they
     * don't match, the pointer addresses the first character that doesn't match.
     */
    const char *match(const char *str)
    {
            if( *str == '\0' || *str == ')' ) { return str; }
            if( *str == '(' )
            {
                    const char *closer = match(++str);
                    if( *closer == ')' )
                    {
                            return match(++closer);
                    }
                    return str - 1;
            }
    
            return match(++str);
    }
    

    Tested with this code:

        const char *test[] = {
                "()", "(", ")", "", "(()))", "(((())))", "()()(()())",
                "(() ( hi))) (())()(((( ))))", "abcd"
        };
    
        for( index = 0; index < sizeof(test) / sizeof(test[0]); ++index ) {
                const char *result = match(test[index]);
    
                printf("%s:\t", test[index]);
                *result == '\0' ? printf("Good!\n") :
                        printf("Bad @ char %d\n", result - test[index] + 1);
        }
    

    Output:

    (): Good!
    (:  Bad @ char 1
    ):  Bad @ char 1
    :   Good!
    (())):      Bad @ char 5
    (((()))):   Good!
    ()()(()()): Good!
    (() ( hi))) (())()(((( )))):    Bad @ char 11
    abcd:       Good!
    
    0 讨论(0)
  • 2020-11-29 18:19
    func evalExpression(inStringArray:[String])-> Bool{
        var status = false
        var inStringArray = inStringArray
        if inStringArray.count == 0 {
            return true
        }
    
        // determine the complimentary bracket.
        var complimentaryChar = ""
        if (inStringArray.first == "(" || inStringArray.first == "[" || inStringArray.first == "{"){
            switch inStringArray.first! {
            case "(":
                complimentaryChar = ")"
                break
            case "[":
                complimentaryChar = "]"
                break
            case "{":
                complimentaryChar = "}"
                break
            default:
                break
            }
        }else{
            return false
        }
    
        // find the complimentary character index in the input array.
        var index = 0
        var subArray = [String]()
        for i in 0..<inStringArray.count{
            if inStringArray[i] == complimentaryChar {
                index = i
            }
        }
        // if no complimetary bracket is found,so return false.
        if index == 0{
            return false
        }
        // create a new sub array for evaluating the brackets.
        for i in 0...index{
            subArray.append(inStringArray[i])
        }
    
        subArray.removeFirst()
        subArray.removeLast()
    
        if evalExpression(inStringArray: subArray){
            // if part of the expression evaluates to true continue with the rest.
            for _ in 0...index{
                inStringArray.removeFirst()
            }
            status = evalExpression(inStringArray: inStringArray)
        }
    
        return status
    }
    
    0 讨论(0)
  • 2020-11-29 18:22

    PHP Solution to check balanced parentheses

    <?php
    /**
     * @param string $inputString
     */
    function isBalanced($inputString)
    {
        if (0 == strlen($inputString)) {
            echo 'String length should be greater than 0';
            exit;
        }
    
        $stack = array();
        for ($i = 0; $i < strlen($inputString); $i++) {
            $char = $inputString[$i];
            if ($char === '(' || $char === '{' || $char === '[') {
                array_push($stack, $char);
            }
            if ($char === ')' || $char === '}' || $char === ']') {
                $matchablePairBraces = array_pop($stack);
                $isMatchingPair = isMatchingPair($char, $matchablePairBraces);
                if (!$isMatchingPair) {
                    echo "$inputString is NOT Balanced." . PHP_EOL;
                    exit;
                }
            }
        }
        echo "$inputString is Balanced." . PHP_EOL;
    }
    
    /**
     * @param string $char1
     * @param string $char2
     * @return bool
     */
    function isMatchingPair($char1, $char2)
    {
        if ($char1 === ')' && $char2 === '(') {
            return true;
        }
        if ($char1 === '}' && $char2 === '{') {
            return true;
        }
        if ($char1 === ']' && $char2 === '[') {
            return true;
        }
        return false;
    }
    
    $inputString = '{ Swatantra (() {} ()) Kumar }';
    isBalanced($inputString);
    ?>
    
    0 讨论(0)
  • 2020-11-29 18:23

    @indiv's answer is nice and enough to solve the parentheses grammar problems. If you want to use stack or do not want to use recursive method you can look at the python script on github. It is simple and fast.

    BRACKET_ROUND_OPEN = '('
    BRACKET_ROUND__CLOSE = ')'
    BRACKET_CURLY_OPEN = '{'
    BRACKET_CURLY_CLOSE = '}'
    BRACKET_SQUARE_OPEN = '['
    BRACKET_SQUARE_CLOSE = ']'
    
    TUPLE_OPEN_CLOSE = [(BRACKET_ROUND_OPEN,BRACKET_ROUND__CLOSE),
                        (BRACKET_CURLY_OPEN,BRACKET_CURLY_CLOSE),
                        (BRACKET_SQUARE_OPEN,BRACKET_SQUARE_CLOSE)]
    BRACKET_LIST = [BRACKET_ROUND_OPEN,BRACKET_ROUND__CLOSE,BRACKET_CURLY_OPEN,BRACKET_CURLY_CLOSE,BRACKET_SQUARE_OPEN,BRACKET_SQUARE_CLOSE]
    
    def balanced_parentheses(expression):
        stack = list()
        left = expression[0]
        for exp in expression:
            if exp not in BRACKET_LIST:
                continue
            skip = False
            for bracket_couple in TUPLE_OPEN_CLOSE:
                if exp != bracket_couple[0] and exp != bracket_couple[1]:
                    continue
                if left == bracket_couple[0] and exp == bracket_couple[1]:
                    if len(stack) == 0:
                        return False
                    stack.pop()
                    skip = True
                    left = ''
                    if len(stack) > 0:
                        left = stack[len(stack) - 1]
            if not skip:
                left = exp
                stack.append(exp)
    
        return len(stack) == 0
    if __name__ == '__main__':
        print(balanced_parentheses('(()())({})[]'))#True
        print(balanced_parentheses('((balanced)(parentheses))({})[]'))#True
        print(balanced_parentheses('(()())())'))#False
    
    0 讨论(0)
  • 2020-11-29 18:28
     public static boolean isBalanced(String str) {
        if (str.length() == 0) {
            return true;
        }
        if (str.contains("()")) {
            return isBalanced(str.replaceFirst("\\(\\)", ""));
        }
    
        if (str.contains("[]")) {
            return isBalanced(str.replaceFirst("\\[\\]", ""));
        }
        if (str.contains("{}")) {
            return isBalanced(str.replaceFirst("\\{\\}", ""));
        } else {
            return false;
        }
    }
    
    0 讨论(0)
  • 2020-11-29 18:31

    It should be a simple use of stack ..

    private string tokens = "{([<})]>";        
        Stack<char> stack = new Stack<char>();   
    
        public bool  IsExpressionVaild(string exp)
        {
            int mid = (tokens.Length / 2)  ;  
    
            for (int i = 0; i < exp.Length; i++)
            {
                int index = tokens.IndexOf(exp[i]);
                if (-1 == index) { continue; }
    
                if(index<mid ) stack .Push(exp[i]);
                else 
                {
                    if (stack.Pop() != tokens[index - mid]) { return false; }       
    
                }          
    
            }
            return true;       
    
        }
    
    0 讨论(0)
提交回复
热议问题