这个堆栈溢出线程声称每个递归函数都可以写成循环。
Which recursive functions cannot be rewritten using loops?
这完全合情合理。但我不确定如何将以下递归函数表示为循环,因为它具有预递归逻辑和后递归逻辑。
显然解决方案不能使用goto语句。代码在这里:
def gen_perms(lst, k, m):
if k == m:
all_perms.append(list(lst))
else:
for i in xrange(k, m+1):
#swap char
tmp = lst[k]
lst[k] = lst[i]
lst[i] = tmp
gen_perms(lst, k+1, m)
#swap char
tmp = lst[k]
lst[k] = lst[i]
lst[i] = tmp
调用它将是这样的:
all_perms = []
gen_perm([1, 2, 3], 0, 2)
并生成列表1,2,3的每个排列。
答案 0 :(得分:3)
进行排列的最pythonic方法是使用:
>>> from itertools import permutations
>>> permutations([1,2,3])
>>> list(permutations([1,2,3]))
[(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]
答案 1 :(得分:1)
假设你想要找到[1,2,3,4]的所有排列。这些中有24(= 4!),所以将它们编号为0-23。我们想要的是一种非递归的方法来找到第N个排列。
假设我们按照递增的数字顺序对排列进行排序。然后:
因此,我们可以通过将N除以6(= 3!)得到第一个排列数N,然后向上舍入。
我们如何获得下一个号码?查看排列0-5中的第二个数字:
我们在排列6-11中看到类似的事情:
一般情况下,先将除以6后的余数除以2(= 2!),然后向上舍入。这给你1,2或3,第二项是列表中剩下的第1,第2或第3项(在你取出第一项后)。
你可以继续这样做。以下是一些代码:
from math import factorial
def gen_perms(lst):
all_perms = []
# Find the number of permutations.
num_perms = factorial(len(lst))
for i in range(num_perms):
# Generate the ith permutation.
perm = []
remainder = i
# Clone the list so we can remove items from it as we
# add them to our permutation.
items = lst[:]
# Pick out each item in turn.
for j in range(len(lst) - 1):
# Divide the remainder at the previous step by the
# next factorial down, to get the item number.
divisor = factorial(len(lst) - j - 1)
item_num = remainder / divisor
# Add the item to the permutation, and remove it
# from the list of available items.
perm.append(items[item_num])
items.remove(items[item_num])
# Take the remainder for the next step.
remainder = remainder % divisor
# Only one item left - add it to the permutation.
perm.append(items[0])
# Add the permutation to the list.
all_perms.append(perm)
return all_perms
答案 2 :(得分:0)
我对python语法不太熟悉,但是下面的代码(在'c'中)不应该太难翻译,假设python可以嵌套语句。
int list[3]={1,2,3};
int i,j,k;
for(i=0;i < SIZE;i++)
for(j=0;j < SIZE;j++)
for(k=0;k < SIZE;k++)
if(i!=j && j!=k && i!=k)
printf("%d%d%d\n",list[i],list[j],list[k]);