【问题标题】:How to stop the stack from overflowing when generating permutations in python在python中生成排列时如何阻止堆栈溢出
【发布时间】:2016-02-26 12:04:26
【问题描述】:

我正在尝试在不使用 itertools 的情况下在 python 中生成排列。到目前为止,这是我的代码:

def generatePermutations(minVal, maxVal, arrayLength, depth = -1, array = []):
    if(depth == -1): # set all values to minVal initially
        for i in range(arrayLength):
            array.append(minVal)
        depth += 1
        generatePermutations(minVal, maxVal, arrayLength, depth, array) # recurse

    elif depth < arrayLength:
        a.append(array[:]) # a is a list declared above the function

        current = 0
        while current <= depth:
            if array[current] < maxVal:
                array[current] += 1
                break
            else:
                if current < depth:
                    array[current] = minVal
                else:
                    depth += 1
                    array[current] = minVal
                    if depth < arrayLength:
                        array[depth] += 1
                    break
            current += 1

        generatePermutations(minVal, maxVal, arrayLength, depth, array)

该函数适用于足够小的数字集。例如,generatePermutations(1,2,2) 使用以下内容填充列表 a

[1, 1]
[2, 1]
[1, 2]
[2, 2]

但是,当我尝试创建长度为 9 (generatePermutations(1,9,9)) 的数组的排列时,我在函数完成之前很久就遇到了堆栈溢出错误。有什么办法可以预防吗?

【问题讨论】:

  • 你试过itertools了吗? import itertools itertools.permutations([1, 2, 3, 4, 5]) 没关系,我只看了第一句话:)
  • @rocksteady,我知道 itertools 有效,但我想尝试创建自己的函数
  • 我对“编程语言”课程的理解告诉我,具有递归函数的动态范围结构化编程语言只需为每个递归调用消耗调用堆栈,因此足够大的问题规模必须能够填满调用栈。通过重写将尾递归更改为迭代应该是正确的方法。

标签: python stack-overflow permutation


【解决方案1】:

我做了一些测试,发现你的函数的设置方式,它为每一个排列调用自己。如中,递归深度与到目前为止生成的排列数相同。当您尝试执行generatePermutations(1,9,9) 时,Python 会尝试递归到9!=362880 深度,这太深了(仅限于1000)。

相反,重构您的代码,以便您遍历a 中的每个元素,附加当前数字,并在循环中为每个数字执行此操作。这样,递归只需要深入 9 层。

【讨论】:

    猜你喜欢
    • 2011-07-26
    • 2012-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-02
    • 1970-01-01
    • 2019-05-18
    • 1970-01-01
    相关资源
    最近更新 更多