defGetNumList(n, k): """ n, k:正整数,n >= k 返回:二级嵌套列表,大列表中嵌套若干个小列表,例:[[1,2], [1,1,1]] 该函数得到一个可能的数目列表,不包含排序 """ resultList = [] # k = 1,生成一个全是1的列表 if k == 1: l = [] for i inrange(n): l += [1] resultList = [l] # k > 1 else: # GetNumList(n, k) = GetNumList(n, k-1) + 有至少一个数等于k时的组合 r = n // k # n除以k的整数部分 for a inrange(1, r + 1): # a为k出现的次数,范围为1, 2, ..., r recurList = GetNumList(n - a * k, k - 1) # 递归 # 遍历recuList中的每个小列表 for l in recurList: # 有几个k就在小列表中添加几次k for each_a inrange(a): l.append(k) resultList += recurList # 遍历完recuList后,添加到resultList resultList += GetNumList(n, k - 1) return resultList
defGetCombList(n, k): """ n, k:正整数,n >= k 返回:二级嵌套列表,所有数字排列枚举(相同元素看做相同的排列) 如果不区分小球,该列表长度即为组合数 """ resultList = GetNumList(n, k) combList = [] for i inrange(len(resultList)): for item in itertools.permutations(resultList[i]): iflist(item) notin combList: combList.append(list(item)) return combList