问题: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--;
}
}
完整的代码在这。