n个括号的所有合理排列

# -* coding: utf-8 -*-

'''
问题:合法括号组合的生成

描述
    给定括号的个数n,编写程序生成所有格式正确的括号组合。

输入格式
    输入一个整数。

输出格式
    输出为一个列表,每个元素是一个字符串,表示一个可能的括号组合。

输入输出例
    输入                                      输出
    3                   ['((()))', '(()())', '(())()', '()(())', '()()()']
'''


'''
[长生桥分析法]

[1] 将n个括号的合理排列分为n行;
[2] 在第1行的所有排列中,每个排列的最外层只有1个括号,该括号内嵌套n - 1个括号的所有排列;
[3] 在第2行的所有排列中,每个排列的最外层只有2个括号,这2个括号内组合嵌套n - 2个括号的所有排列;
...
[4] 在第n行的所有排列中,每个排列的最外层有n个括号。

[分析举例-3个括号的排列]
[1] (2)
[2] (0)(1) (1)(0)   # 该问题可以看成整数3拆分为2个整数之和的问题
[3] (0)(0)(0)
'''

# 该方法的非递归编码会遇到以下比较复杂的问题,
#   [1] 将正整数n拆分为m个整数之和;
#   [2] 不确定个数 (m)...(k) 的排列,
#       举例(2)(2)的排列:(2)有((()))和(()())两种排列,
#       那么(2)(2)就有4种排列,那么(2)(2)(2)...
#   不好用一个统一的方法确定不定个数 (m)...(k)的排列
# 所以,暂放弃用编程实现该方法

'''
[理解流行的递归排列法]

(1) 先排列'('。在'('后,有两种继续排列的情况:
[1] 排')';
[2] 若还剩有'(',则继续在'('后排'(';
每个'('后所出现的排列都需要被保存下来供后续排列,直至一种排列结束。

(2) 在')'后:
[1] 若剩余的')'数为0,则排列结束,得到“一种”排列;
[2] 若还剩有')'且剩')'的剩余数大于'('的剩余数,则可继续排')';
[3] 若还剩余'(',则可继续排')';
每个')'后所出现的排列都需要被保存下来供后续排列,直至一种排列结束。
'''
# nb_rank_all: 排列一个'('或')'后继续排列时,排列所有可能的情况;
# nb_list:  存储n个括号所有排列的list;
# ob_rank: 存储n个括号某一种排列;
# nll:      '('剩余数;
# nrl:      ')'剩余数
def nb_rank_all_rec(nb_list, ob_rank, nll, nrl):
    if 0 == nrl:
        nb_list.append(ob_rank)
        return 

    # 需要理解类似函数栈帧机制 - 参数的传递

    # 最开始排列'('和排列')'后可排列'('的情况
    if nll > 0:
        nb_rank_all_rec(nb_list, ob_rank + '(', nll - 1, nrl)

    # 排列'('和')'后可排列')'的情况
    if (nrl > 0) and (nrl > nll):
        nb_rank_all_rec(nb_list, ob_rank + ')', nll, nrl - 1)
    return 

nb_list = []
ob_rank = ''
nll = nrl = int(raw_input())
nb_rank_all_rec(nb_list, ob_rank, nll, nrl)
print nb_list

猜你喜欢

转载自blog.csdn.net/misskissC/article/details/81054171