递归解决方案的制定(循环变量)

时间:2013-04-24 13:44:43

标签: python recursion for-loop

请考虑以下算法:

  for(j1 = n upto 0)
     for(j2 = n-j1 upto 0)
       for(j3 = n-j1-j2 upto 0)
        .
         .
           for (jmax = n -j1 - j2 - j_(max-1))
            {
             count++;
             product.append(j1 * j2 ... jmax); // just an example
            }

正如您所看到的,关于以上算法片段的一些相关要点:

  1. 我列出了一个带有可变数量的for循环的算法。
  2. 我在每个最里面的循环中计算的结果被附加到列表中。此列表将增加到“count”的维度。
  3. 此问题是否适合递归?如果是的话,我真的不确定如何解决问题。我试图在python中编写代码,我不希望你们有任何代码。只是在正确的方向上的一些指针或例子。谢谢。

    以下是示例案例http://pastebin.com/PiLNTWED

    的初步尝试

5 个答案:

答案 0 :(得分:1)

您还可以考虑使用 itertools 模块中的排列,组合或产品。 如果你想要i,j,k,......的所有可能组合(即嵌套for循环) 你可以使用:

for p in product(range(n), repeat=depth):
    j1, j2, j3, ... = p # the same as nested for loops
    # do stuff here

但要注意,循环中的迭代次数呈指数级增长!

答案 1 :(得分:1)

您的算法正在查找所有m - 元组(m是来自您的伪代码的max的{​​{1}}下标)非负整数,加起来为{ {1}}或更少。在Python中,最自然的表达方式是使用递归生成器:

j

示例输出:

n

答案 2 :(得分:0)

玩具示例将转换为一种尾递归,因此,个人而言,我不希望递归版本对代码审查和维护更具洞察力。

然而,为了熟悉这个原理,尝试从单个循环中分解出不变的部分/常用术语,并尝试识别一个模式(最好在之后证明它!)。您应该能够修复要写入的递归过程的签名。用循环体固有的部分来充实它(并且不要忘记终止条件)。

答案 3 :(得分:0)

通常,如果要将for循环转换为递归调用,则需要将for语句替换为if语句。对于嵌套循环,您将把它们转换为函数调用。

对于练习,首先是对有效代码进行愚蠢的翻译,然后尝试查看以后可以优化的位置。

为了让你有机会尝试适用于你的情况,我会翻译这样的事情:

results = []
for i in range(n):
    results.append(do_stuff(i, n))

这样的事情:

results = []

def loop(n, results, i=0):
    if i >= n:
        return results
    results.append(do_stuff(i, n))
    i += 1
    loop(n, results, i)

有不同的方法可以处理返回结果列表,但您可以根据自己的需要进行调整。

答案 4 :(得分:0)

- 作为对Blckgnht优秀列表的回应 - 在此考虑n = 2和max = 3的情况

def simpletest():    

    '''
    I am going to just test the algo listing with assumption
    degree n = 2
    max = dim(m_p(n-1)) = 3, 
    so j1 j2 and upto j3 are required for every entry into m_p(degree2)
    Lets just print j1,j2,j3 to verify if the function
    works in other general version where the number of for loops is not known
    '''
    n = 2
    count = 0
    for j1 in range(n, -1, -1):
        for j2 in range(n -j1, -1, -1):
            j3 = (n-(j1+j2)) 
            count = count + 1
            print 'To calculate m_p(%d)[%d], j1,j2,j3 = ' %(n,count), j1, j2, j3

    assert(count==6)        # just a checkpoint. See P.169 for a proof
    print 'No. of entries =', count    

此代码的输出(并且它是正确的)。

    In [54]: %run _myCode/Python/invariant_hack.py
To calculate m_p(2)[1], j1,j2,j3 =  2 0 0
To calculate m_p(2)[2], j1,j2,j3 =  1 1 0
To calculate m_p(2)[3], j1,j2,j3 =  1 0 1
To calculate m_p(2)[4], j1,j2,j3 =  0 2 0
To calculate m_p(2)[5], j1,j2,j3 =  0 1 1
To calculate m_p(2)[6], j1,j2,j3 =  0 0 2
No. of entries = 6