我提出了以下功能:
def permutations(elements, arr, index):
if len(elements) == index:
print arr
for i in xrange(index, len(elements)):
arr[index] = elements[i]
permutations(elements, arr, index+1)
permutations([1,2,3], [0,0,0], 0)
然而,正在打印:
[1, 2, 3]
[1, 3, 3]
[2, 2, 3]
[2, 3, 3]
[3, 2, 3]
[3, 3, 3]
我的递归出了什么问题?
答案 0 :(得分:1)
好的,我发现这是我翻译成Python的Java String递归排列算法。我认为这是最好的解决方案:
def permutation(aux, ls):
if len(ls) == 0:
print(aux)
else:
for i in range(len(ls)):
permutation(aux + [ls[i]], ls[0:i] + ls[i+1:len(ls)])
permutation([], [1, 2, 3])
这是输出:
[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 1, 2]
[3, 2, 1]
答案 1 :(得分:0)
代码中的主要问题是,在i-th
位置上,只有可能的值来自(i, n - 1)
,其中n是列表的长度。这就是为什么在列表中的最后一个索引你有所有3#s。因此,解决方案是迭代所有"级别"来自i-th
的((0, n - 1)
排列调用)。但是因为你将在所有"等级上从(0, n - 1)
迭代。如果在之前的调用中已经选择了某个值(j-th
元素),则必须引入字典(用作hashset)。最简单的解决方案就是:
def perm(elements):
def inner(arr, index, visited):
if len(elements) == index:
print arr
for i in xrange(0, len(elements)):
if (i not in visited):
visited[i] = 1; # mark so same index can not be used later
arr[index] = elements[i]
inner(arr, index + 1, visited);
del visited[i] # free index
inner([0] * len(elements), 0, {});
perm([1,2,3])
正如@Hooked已经提到的那样,最好能使用permutations function from itertools module。请注意,在Python 3上,您可以使用nonlocal
将arr和访问的函数参数放在外部。此外,这里还有一个解决方案,没有字典,但附加列表将保存排列的i-th
级别(位置)的所有可能值。在该解决方案中,但是不保留排列的顺序
def perm(elements):
def inner(arr, index, possible):
if len(elements) == index:
print arr
lenForLevel = len(elements) - index;
for i in xrange(0, lenForLevel):
arr[index] = possible[i]
(possible[i], possible[lenForLevel - 1]) = (possible[lenForLevel - 1], possible[i])
inner(arr, index + 1, possible);
(possible[i], possible[lenForLevel - 1]) = (possible[lenForLevel - 1], possible[i])
inner([0] * len(elements), 0, list(elements))
perm([1,2,3,4])