問題: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--; }}
完整的代碼在這。