问题:n个左括号,n个右括号,请打印出所有合法的括号序列。所谓合法是指对每一个右括号,在它左侧有一个左括号和它匹配。

举例:

n=2时,合法的序列有()()和(()),不合法的序列有())(,))((,)()(和)(()

分析:我们已经知道这是一个卡特兰数问题,其总共可能的合法序列数是C2nn。那么如何产生这些序列呢?可以这么理解:给定一个n个左括号和n个右括号构成的序列,该序列合法的充分必要条件就是对每一个右括号,其左侧子序列有一个左括号与其匹配。什么时候没有这种左括号与其配对呢?就是当它左侧的左括号和右括号数正好相等的时候。因此我们知道,在长为2n的序列的任一个位置,我们有如下选择:

1、如果还有左括号没有用完,就放置一个左括号,未使用的左括号数减1;或者
2、如果已经生成的子序列中左括号数大于右括号数,就放置一个右括号,未使用的右括号数减一
3、不管放置了左括号还是右括号,生成的子序列长度加一;如果还有未使用的左括号或右括号,跳到第1步

第3步中,如果已经没有未使用的左括号和右括号,说明一个序列已经生成了。

C语言的实现:

typedef enum _PARENTHESIS {                     /* Parenthesis type */
    NONE,
    LEFT,
    RIGHT
} PARENTHESIS;

int n;
PARENTHESIS stack[MAX_PAIRS * 2 + 1] = {NONE, };/* Simulate parenthesis stack */
int ind;                                        /* Current stack location */

/**
 * matching_parenthesis_pairs
 *
 * Generate matching parenthesis pair sequences in a simulated stack.
 * Initially call matching_parenthesis_pairs(0, 0)
 *
 * @param left_in_stack Current number of left parentheses in stack
 * @param right_in_stack Current number of right parentheses in stack
 */
void matching_parenthesis_pairs(int left_in_stack, int right_in_stack)
{
    if (left_in_stack < right_in_stack) {
        return;
    }

    if (ind == n * 2 + 1)
    {
        print_stack();
        return;
    }

    if (left_in_stack < n) {
        stack[ind++] = LEFT;
        matching_parenthesis_pairs(left_in_stack + 1, right_in_stack);
        ind--;
    }
    if (right_in_stack < left_in_stack) {
        stack[ind++]= RIGHT;
        matching_parenthesis_pairs(left_in_stack, right_in_stack + 1);
        ind--;
    }
}

完整的代码在这

相关文章: