此程序需要通过使用此规则交换元素来查找列表的所有排列 - 交换最后一个元素直到它成为第一个(例如1,2,3,4变为1,2,4,3等等,直到4 ,1,2,3),当它成为第一个元素时,你需要切换最后2个元素并在相反的方向做同样的事情(交换第一个元素,直到它变为最后一个然后交换前2个元素并重复),这是也被称为Steinhaus - Johnson - Trotter算法。出于某种原因,我的实现并不是在Python中工作,我想知道为什么以及我需要做些什么来使它工作。
编辑:通过"不工作"我的意思是程序只打印list1而不执行任何其他操作,程序只能通过" kill"它意味着它被卡在无限循环中(这可以通过在将list1附加到all_permutations之后打印all_permutations来证明。)
list1 = [0, 1, 2, 3] #list that will be swapped
x = 3 #this is used for swapping
all_permutations = [] #list where permutations will be added
print(list1) #print list1 because it is the first permutation
while len(all_permutations) != 23: #loop until all permutations are found (4! = 24 but since list1 is already 1 permutation we only need 23)
x -= 1
list1[x], list1[x+1] = list1[x+1], list1[x]
all_permutations.append(list1)
#code above swaps the last element until it becomes 1st in the list
if x == 0: #if last element becomes 1st
list1[2], list1[3] = list1[3], list1[2] #swap last 2 elements
while x != 3: #loop which swaps 1st element until it becomes the last element
if len(all_permutations) == 23:
break
else:
continue
x += 1
list1[x-1], list1[x] = list1[x], list1[x-1]
all_permutations.append(list1)
list1[0], list1[1] = list1[1], list1[0] #when loop is over (when 1st element becomes last) switch first 2 elements
all_permutations.append(list1)
else:
continue
print(all_permutations) #print all permutations
答案 0 :(得分:2)
while x != 3:
if len(all_permutations) == 23:
break
else:
continue
此处的这段代码将导致无限循环。如果all_permutations
的长度不是23,则会触及continue
语句。这会将程序发送回循环的开头,而不会修改x
或all_permutations
。
我相信你在这里寻找的是pass
,它什么都不做。 continue
将回到循环的开头。因此,要修复程序的这一部分,您实际上可以完全摆脱else
,因为break
无论如何都会退出循环。
while x != 3:
if len(all_permutations) == 23:
break
x += 1
list1[x-1], list1[x] = list1[x], list1[x-1]
all_permutations.append(list1)
或者你可以完全取消if
:
while x != 3 or len(all_permutations) != 23:
x += 1
list1[x-1], list1[x] = list1[x], list1[x-1]
all_permutations.append(list1)
答案 1 :(得分:0)
您正在向all_permutations
添加对同一列表对象的多个引用,并且每次循环时都会修改该列表对象。而是添加列表的副本,以便您拥有一组不同的排列。
all_permutations.append(list1[:])
这是一个错误;无限循环是由于IanAuld指出的问题。
答案 2 :(得分:0)
http://pastebin.com/bY7ZznR1处的新代码陷入无限循环的原因是,当masterData.addAll(wrapper.getFiles());
在内部len(all_permutations) == 23
循环中变为True时,您会在第30行附加另一个列表。当控制到达外循环while
的顶部时,循环继续执行。
这很容易修复,但是你的算法不太正确。我已经修改了你的代码以生成任意大小的列表的排列,并注意到它为长度为3或4的列表提供了正确的结果,但是对于长度为2或5的列表则没有;我没有费心去测试其他尺寸。
FWIW,这是一个实现Steinhaus - Johnson - Trotter算法的递归版本的程序。如果您想改进迭代算法,可能会发现它很有用。
len(all_permutations) == 24
<强>输出强>
#!/usr/bin/env python
''' Generate permutations using the Steinhaus - Johnson - Trotter algorithm
This generates permutations in the order known to bell ringers as
"plain changes".
See https://en.wikipedia.org/wiki/Steinhaus%E2%80%93Johnson%E2%80%93Trotter_algorithm
From http://stackoverflow.com/q/31209826/4014959
Written by PM 2Ring 2015.07.03
'''
import sys
def sjt_permute(items):
num = len(items)
if num == 1:
yield items[:1]
return
last = items[-1:]
uprange = range(num)
dnrange = uprange[::-1]
descend = True
for perm in sjt_permute(items[:-1]):
rng = dnrange if descend else uprange
for i in rng:
yield perm[:i] + last + perm[i:]
descend = not descend
def main():
num = int(sys.argv[1]) if len(sys.argv) > 1 else 4
items = range(num)
for p in sjt_permute(items):
print(p)
if __name__ == '__main__':
main()