例如
dic = {0 : 1, 1 : 3, 2 : 5, 3 : 9, 4 : 4}
SUM = 9
抽取组合为
- 3:9
- 2:5 4:4 (5+4=9)
- 0:1 1:3 2:5 (1+3+5=9)
本程序的思路是开一个数组,其下标表示1到m个数,数组元素的值为1表示其下标
代表的数被选中,为0则没选中。
首先初始化,将数组前n个元素置1,表示第一个组合为前n个数。
然后从左到右扫描数组元素值的“10”组合,找到第一个“10”组合后将其变为
“01”组合,同时将其左边的所有“1”全部移动到数组的最左端。
当第一个“1”移动到数组的m-n的位置,即n个“1”全部移动到最右端时,就得
到了最后一个组合。
例如求5中选3的组合:
1 1 1 0 0 //1,2,3 1 1 0 1 0 //1,2,4 1 0 1 1 0 //1,3,4 0 1 1 1 0 //2,3,4 1 1 0 0 1 //1,2,5 1 0 1 0 1 //1,3,5 0 1 1 0 1 //2,3,5 1 0 0 1 1 //1,4,5 0 1 0 1 1 //2,4,5 0 0 1 1 1 //3,4,5
因此非递归实现的大致代码如下:
#coding=utf-8 #从m个数字里面抽出来n个 def sum(pos,target): sum = 0 for i in range(len(pos)): if pos[i] == 1: sum += dic[i] if sum == target: return True def leftfix(index,onecount,pos,target): if index >= 2 and index < len(pos)-2: pos[0:index] = [1]*onecount+[0]*(index-onecount) if sum(pos,target): print pos def find(m ,n ,target): pos = [1]*n+[0]*(m-n) if sum(pos,target): print pos i = 0 j = 0 while True: if i>=len(pos)-1:break if pos[i] == 1: j += 1 if pos[i+1] == 0: j -= 1 #之前的i个数字里面有j个1 i-j个0 pos[i], pos[i + 1] = pos[i + 1], pos[i] if sum(pos,target): print pos leftfix(i,j,pos,target) i = -1 j = 0 i+=1 dic = {0 : 1, 1 : 3, 2 : 5, 3 : 9, 4 : 4} for n in range(1,len(dic)+1): find(len(dic),n,9)
时间: 2024-10-21 02:25:40