簡體   English   中英

使for循環和if語句的遞歸函數成為迭代函數

[英]Make recursive function of for loops and if statements into iterative function

面臨的挑戰是找到小於N且其總和等於N的數字的所有可能組合。例如,當N等於:

  • 2
    • 1 + 1-1路
  • 3
    • 2 + 1
    • 1 + 1 + 1-2種方式
  • 4
    • 3 + 1
    • 2 + 2
    • 2 + 1 + 1
    • 1 + 1 + 1 + 1-4種方式

等等...

現在在python中創建它,以了解模式,我起草了以下代碼1st:

N=5
for d in drange(0,N,1):
    if N-d*4>=0:
        for c in drange(0,N,1):
            if N-d*4-c*3>=0:
                for b in drange(0,N,1):
                    if N-d*4-c*3-b*2>=0:
                        for a in drange(0,N,1):
                            if N-d*4-c*3-b*2-a*1==0:
                                if sum([d,c,b,a])!=1:
                                    print d,c,b,a                            
                    else: break
            else:break
    else:break
  1. 然后我將代碼更改為N = 6及以下的代碼:
 N=6 for e in drange(0,N,1): if Ne*5>=0: C0 = Ne*5 for d in drange(0,N,1): if C0-d*4>=0: C1 = C0-d*4 for c in drange(0,N,1): if C1-c*3>=0: C2 = C1-c*3 for b in drange(0,N,1): if C2-b*2>=0: C3 = C2-b*2 for a in drange(0,N,1): if C3-a*1==0: if sum([e,d,c,b,a])!=1: print e,d,c,b,a else: break else:break else:break else:break 
  1. 下一版本合並了數組以跟蹤數字並節省計算空間:
 N=6 Nums = drange2(6-1,-1,-1) Vals = [0]*6 Vars = [0]*6 for Vars[0] in drange(0,N,1): if N-Vars[0]*Nums[0]>=0: Vals[0] = N-Vars[0]*Nums[0] for Vars[1] in drange(0,N,1): if Vals[0]-Vars[1]*Nums[1]>=0: Vals[1] = Vals[0]-Vars[1]*Nums[1] for Vars[2] in drange(0,N,1): if Vals[1]-Vars[2]*Nums[2]>=0: Vals[2] = Vals[1]-Vars[2]*Nums[2] for Vars[3] in drange(0,N,1): if Vals[2]-Vars[3]*Nums[3]>=0: Vals[3] = Vals[2]-Vars[3]*Nums[3] for Vars[4] in drange(0,N,1): if Vals[3]-Vars[4]*Nums[4]==0: if sum([Vars[0],Vars[1],Vars[2],Vars[3],Vars[4]])!=1: print Vars else: break else:break else:break else:break 
  1. 然后我想使此代碼在N為100時起作用,我使其遞歸...
 N=48 Nums = drange2(N-1,-1,-1) Vals = [0]*N Vars = [0]*(N-1) count=0 def sumCombos(Number,i): if i==0: global count for Vars[i] in xrange(0,i+2,1): z = Number-Vars[i]*Nums[i] if z>=0: Vals[i] = z sumCombos(Number,i+1) else: break elif i<Number-2: for Vars[i] in xrange(0,i+1,1): z = Vals[i-1]-Vars[i]*Nums[i] if z >=0: Vals[i]=z sumCombos(Number,i+1) else: break elif i==Number-2: for Vars[i] in xrange(0,i+3,1): if Vals[i-1]-Vars[i]*Nums[i]==0: count+=1 sumCombos(N,0) print count 
  1. 問題:由於調用了1000000多個方法,這花費了太多時間,所以有沒有辦法在我無需輸入所有內容的情況下創建先前的層疊效果的地方進行這種迭代? 我在網站和其他網站上搜索了如何制作涉及for循環和if語句迭代的遞歸函數,但是對於這一特定函數卻沒有走運。 請提供任何智慧-Shaha3

你為什么要它遞歸?

>>> from itertools import chain, combinations_with_replacement
>>> n = 7
>>> [i for i in chain.from_iterable(
       combinations_with_replacement(range(1, n), k)
       for k in range(2, n+1))
     if sum(i) == n]

[(1, 6), (2, 5), (3, 4), (1, 1, 5), (1, 2, 4), (1, 3, 3), (2, 2, 3), (1, 1, 1, 4), (1, 1, 2, 3), (1, 2, 2, 2), (1, 1, 1, 1, 3), (1, 1, 1, 2, 2), (1, 1, 1, 1, 1, 2), (1, 1, 1, 1, 1, 1, 1)]

這個問題隨着n增長! 因此,要獲取大量數字會花費很多時間。

我猜您正在談論整數分區問題(wiki: http : //en.wikipedia.org/wiki/Partition_ ( number_theory ))可以以迭代方式或遞歸方式完成,盡管可能存在深度限制遞歸方法。 這是我的實現


def partitions(n):
    def next(seq):
        L = len(seq)
        ## start from L-2 element, must have at least one element in suffix
        for i in range(L-2, -1, -1):
            if seq[i-1] and seq[i-1] > seq[i]: break
        remainder = n - sum(seq[:i+1]) - 1
        return seq[:i] + [seq[i]+1] + [1 for _ in range(remainder)]
    start, end = [1 for _ in range(n)], [n]
    seq = start
    while True:
        yield seq
        if seq >= end: break
        seq = next(seq)

# test cases
if __name__ == '__main__':
    ## test partitions
    assert list(partitions(4)) == [[1, 1, 1, 1], [2, 1, 1], [2, 2], [3, 1], [4]]
    assert list(partitions(5)) == [
        [1, 1, 1, 1, 1], 
        [2, 1, 1, 1], [2, 2, 1], 
        [3, 1, 1], [3, 2], 
        [4, 1], 
        [5]]

    print 'all tests passed'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM