最近玩小游戏写脚本遇到一个问题,要用一个堆数字比如[2,5,2,2,6],用其中的元素求和组成某一个数字比如12,可以知道答案是[2,2,2,6]。那么如何使用代码让它实现出来呢?
我想了很久,最后想了一个利用递归的枝叶裁剪法。比如以上的例子
1.看12是否在数字堆中,不在
2,看11是否在,不在
。。。
4,6在。将6添加到暂时list中[6],那么还需要12-6=6。
5,6虽然在数字堆中,但是只有一个。所以看5是否在,5在。 list[6,5],需要 12-6-5=1
6,1不在数字堆。所以从list中取出最近添加的元素,5,并减1。 list[6] 需要 4
7,4 不在
8,3不在
9,2在 list[6,2] 需要12-6-2=4
...
12,2在 list[6,2,2] 需要12-6-2-2=2
13 2在 list[6,2,2,2]
这个想法我也不记得从哪参考的了,总之用递归的方法可以逐步实现。此外这个算法的思想是优先添加最大的字数字,如果想要优先添加最小数字,在添加元素的时候就应从1开始,逐步加1。以下是python 实现的代码。
def getsubArr(elementArr,Arr,Sum,Num): '''elementArr:包含所有元素的list;Arr:暂时list;Sum:需要求和的值;Num:哨兵值''' if Num==0: if sum(Arr)==Sum: return Arr #若是求的和已经满足,返回数组 else: newNum = Num tempArr =Arr if len(tempArr)==0: return None #已经搜索所有的可能,没有结果,返回空 else: t = tempArr.pop() return getsubArr(elementArr,tempArr,Sum,t-1) newNum = Num tempArr =Arr if elementArr.count(newNum) > tempArr.count(newNum) and elementArr.count(newNum) > 0: if newNum+sum(Arr) <=Sum: tempArr.append(newNum) return getsubArr(elementArr,tempArr,Sum,Sum-sum(tempArr)) else: return getsubArr(elementArr,tempArr,Sum,newNum-1) else : return getsubArr(elementArr,tempArr,Sum,newNum-1)
使用如下:
print getsubArr([2,3,6,1,8,3,12,18,8,3,7],[],26,26)
输出如下