递归排列生成器,交换列表项不起作用
我想系统地生成字母表的排列。 我不能不想使用 python itertools.permutation,因为预先生成每个排列的列表会导致我的计算机崩溃(我第一次真正用它来强制关闭,这非常棒)。
因此,我的新方法是动态生成和测试每个密钥。目前,我正在尝试用递归来处理这个问题。
我的想法是从最大的列表开始(我将使用 3 元素列表作为示例),递归到较小的列表,直到列表有两个元素长。然后,它将打印列表,交换最后两个,再次打印列表,然后返回上一级并重复。
例如,对于 123
123(位置0与位置0交换)
<前><代码> 23 --> 123(位置 1 与位置 1 交换) 32 --> 132(位置 1 与位置 2 交换)213(位置 0 与位置 1 交换)
<前><代码> 13 --> 213(位置 1 与位置 1 交换) 31 --> 231(位置 1 与位置 2 交换)321(位置 0 与位置 2 交换)
<前><代码> 21 --> 321(位置 1 与位置 1 交换) 12 --> 312(位置 1 与位置 2 交换)
对于四字母数字 (1234),
1234(位置0与位置0交换)
234(位置 1 与位置 1 交换) 34 --> 1234 43 --> 1243 324(位置 1 与位置 2 交换) 24 --> 1324 42 -->第1342章 432(位置 1 与位置 3 交换) 32 -->第1432章 23 --> 1423
2134(将位置 0 交换为位置 1) 134(位置 1 与位置 1 交换) 34 --> 2134 43 --> 2143 314(位置 1 与位置 2 交换) 14--> 2314 41--> 2341 431(位置 1 与位置 3 交换) 31--> 2431 13 -->2413
这是我目前的递归代码,但它给我带来了很多悲伤,递归不是我的强项。这就是我所拥有的。
def perm(x, y, key):
print "Perm called: X=",x,", Y=",y,", key=",key
while (x<y):
print "\tLooping Inward"
print "\t", x," ",y," ", key
x=x+1
key=perm(x, y, key)
swap(x,y,key)
print "\tAfter 'swap':",x," ",y," ", key, "\n"
print "\nFull Depth Reached"
#print key, " SWAPPED:? ",swap(x,y,key)
print swap(x, y, key)
print " X=",x,", Y=",y,", key=",key
return key
def swap(x, y, key):
v=key[x]
key[x]=key[y]
key[y]=v
return key
任何帮助将不胜感激,这是一个非常酷的项目,我不想放弃它。
感谢大家!欢迎对我的方法或任何内容发表评论。
I want to systematically generate permutations of the alphabet.
I cannot don't want to use python itertools.permutation, because pregenerating a list of every permutation causes my computer to crash (first time i actually got it to force a shutdown, it was pretty great).
Therefore, my new approach is to generate and test each key on the fly. Currently, I am trying to handle this with recursion.
My idea is to start with the largest list (i'll use a 3 element list as an example), recurse in to smaller list until the list is two elements long. Then, it will print the list, swap the last two, print the list again, and return up one level and repeat.
For example, for 123
123 (swap position 0 with position 0)
23 --> 123 (swap position 1 with position 1) 32 --> 132 (swap position 1 with position 2)
213 (swap position 0 with position 1)
13 --> 213 (swap position 1 with position 1) 31 --> 231 (swap position 1 with position 2)
321 (swap position 0 with position 2)
21 --> 321 (swap position 1 with position 1) 12 --> 312 (swap position 1 with position 2)
for a four letter number (1234)
1234 (swap position 0 with position 0)
234 (swap position 1 with position 1) 34 --> 1234 43 --> 1243 324 (swap position 1 with position 2) 24 --> 1324 42 --> 1342 432 (swap position 1 with position 3) 32 --> 1432 23 --> 1423
2134 (swap position 0 for position 1)
134 (swap position 1 with position 1)
34 --> 2134
43 --> 2143
314 (swap position 1 with position 2)
14--> 2314
41--> 2341
431 (swap position 1 with position 3)
31--> 2431
13 -->2413
This is the code i currently have for the recursion, but its causing me a lot of grief, recursion not being my strong suit. Here's what i have.
def perm(x, y, key):
print "Perm called: X=",x,", Y=",y,", key=",key
while (x<y):
print "\tLooping Inward"
print "\t", x," ",y," ", key
x=x+1
key=perm(x, y, key)
swap(x,y,key)
print "\tAfter 'swap':",x," ",y," ", key, "\n"
print "\nFull Depth Reached"
#print key, " SWAPPED:? ",swap(x,y,key)
print swap(x, y, key)
print " X=",x,", Y=",y,", key=",key
return key
def swap(x, y, key):
v=key[x]
key[x]=key[y]
key[y]=v
return key
Any help would be greatly appreciated, this is a really cool project and I don't want to abandon it.
Thanks to all! Comments on my method or anything are welcome.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在我职业生涯后期遇到了我的老问题
为了有效地做到这一点,您需要编写一个生成器。
生成器不是返回所有排列的列表(这需要将它们(全部)存储在内存中),而是返回一个排列(此列表的一个元素),然后暂停,然后当您要求时计算下一个。
发电机的优点是:
(Itertools.permutation 是生成器的一个示例)
如何编写生成器?
用 python 编写生成器实际上非常简单。
基本上,编写可用于生成排列列表的代码。现在,不要编写
resultList+=[ resultItem ]
,而是编写yield(resultItem)
。现在你已经制作了一个发电机。如果我想循环我的生成器,我可以写
“就这么简单”。
下面是我很久以前尝试编写的代码的生成器:
Happened upon my old question later in my career
To efficiently do this, you want to write a generator.
Instead of returning a list of all of the permutations, which requires that you store them (all of them) in memory, a generator returns one permutation (one element of this list), then pauses, and then computes the next one when you ask for it.
The advantages to generators are:
(Itertools.permutation is an example of a generator)
How do I Write a Generator?
Writing a generator in python is actually very easy.
Basically, write code that would work for generating a list of permutations. Now, instead of writing
resultList+=[ resultItem ]
, writeyield(resultItem)
.Now you've made a generator. If I wanted to loop over my generator, I could write
It's that easy.
Below is a generator for the code that I tried to write long ago:
我认为你的想法非常好,但是跟踪位置可能会有点难以处理。我见过的递归生成排列的一般方法是一个接受两个字符串参数的函数:一个用于从 (
str
) 中删除字符,另一个用于向 (soFar
) 添加字符)。当生成排列时,我们可以考虑从
str
中获取字符并将它们添加到soFar
中。假设我们有一个函数perm
,它接受这两个参数并查找str
的所有排列。然后我们可以考虑当前字符串str
。我们将从str
中的每个字符开始排列,因此我们只需要循环str
,使用每个字符作为初始字符并对剩余的字符调用 perm在字符串中:I think you have a really good idea, but keeping track of the positions might get a bit difficult to deal with. The general way I've seen for generating permutations recursively is a function which takes two string arguments: one to strip characters from (
str
) and one to add characters to (soFar
).When generating a permutation then we can think of taking characters from
str
and adding them tosoFar
. Assume we have a functionperm
that takes these two arguments and finds all permutations ofstr
. We can then consider the current stringstr
. We'll have permutations beginning with each character instr
so we just need to loop overstr
, using each of these characters as the initial character and calling perm on the characters remaining in the string: