# -* coding: utf-8 -*-
# about_nbrckts.py
# 2018.07.15
# lgt
'''
问题:合法括号组合的生成
描述
给定括号的个数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_rec: 排列一个'('或')'后继续排列时,排列所有可能的情况;
# 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
# 需要理解(类似C语言)函数栈帧机制 - 参数的传递
# 最开始排列'('和排列')'后可排列'('的情况
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
about_nbrckts.py的几次运行结果: