Python3 - 排列组合的迭代
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python3 - 排列组合的迭代相关的知识,希望对你有一定的参考价值。
参考技术A遍历一个序列中元素的所有可能的排列或组合。
itertools 模块提供了三个函数来解决这类问题。 其中一个是 itertools.permutations() , 它接受一个序列并产生一个元组序列,每个元组由序列中所有元素的一个可能排列组成,即通过打乱序列中元素排列顺序生成一个元组,比如:
如果想得到指定长度的所有排列,你可以传递一个可选的长度参数。比如:
使用 itertools.combinations() 可得到输入序列中元素的所有的组合。比如:
对于 combinations() 来讲,元素的顺序已经不重要了,即组合 (\'a\', \'b\') 与 (\'b\', \'a\') 其实是一样的,最终只会输出其中一个。
在计算组合的时候,一旦元素被选取就会从候选中剔除掉(比如如果元素’a’已经被选取了,那么接下来就不会再考虑它了)。 而函数 itertools.combinations_with_replacement() 允许同一个元素被选择多次,比如:
尽管手动可以实现排列组合算法,但是这样做比较麻烦,当遇到有些复杂的迭代问题时,可以先去看看itertools模块是否能实现,很有可能会在里面找到解决方案!
计数和迭代序列的排列
【中文标题】计数和迭代序列的排列【英文标题】:count and iterate arrangements of a sequence 【发布时间】:2012-06-26 00:14:18 【问题描述】:我有一个字符串和一些空格,例如字符串是“accttgagattcagt”,我有 10 个空格要插入。
如何遍历该字符串和空格的所有组合?字符串中的字母不能重新排序,必须全部插入空格。
你如何计算重排的数量(不重复它们)?
什么是合适的词呢?排列、组合还是其他?
(我将其可视化为 1 和 0 的字符串,其中 1 由字符串使用,0 是空格。
因此,由 3 个字母和 2 个空格组成的短字符串将要求所有具有 3 个 1 和 2 个 0 的所有 5 位数字,例如11100、11010、11001、10110、10101、10011、01110、01101、01011、00111?
但是在纸上制作短序列很容易,我正在努力制作一个 for 循环来做到这一点:(。创建这个序列的伪代码非常好,请计算一下它会有多长时间?
递归会更容易理解,但如果以某种方式避免递归会更快吗?)
【问题讨论】:
所以你想要插入空格的字符串的所有排列,而字符串中字符的顺序不会改变? 【参考方案1】:这是组合。
因此,由 3 个字母和 2 个空格组成的短字符串将要求所有具有 3 个 1 和 2 个 0 的所有 5 位数字,例如11100、11010、11001、10110、10101、10011、01110、01101、01011、00111?
您将三个“1”放在 5 个索引之一上,顺序无关紧要。所以它是 5 比 3:
5!/((5-3)!3!) = 5*4/(2*1) = 10
wikipedia.org 上的文章有一张图片,展示了 3 个红色和 2 个白色方块的随机序列。
这可能有用: Statistics: combinations in Python
【讨论】:
谢谢;我从不明白如何表达自己的问题变得自信;一个灯泡时刻。链接也很棒。【参考方案2】:嗯,有点伪代码,但你应该明白了
list doThat(string, spaces)
returnList
spacesTemp = spaces;
for(c = 0; c < string.length; c++)
subString = string.getSubString(c, string.length);
tmpString = string.insertStringAtPosition(c, createSpaceString(spacesTemp);
retSubStringList = doThat(subString, spaces - spacesTemp);
retCombinedList = addStringInFrontOfAllStringsInList(tmpString, retSubStringList);
returnList.addList(retCombinedList);
spacesTemp--;
return returnList;
【讨论】:
【参考方案3】:n - 字母数 m - 空格数
计数
将第一个和第二个字母之间的空格数表示为 a_1,将第二个和第三个字母之间的空格数表示为 a_2,依此类推。您的问题现在可以表述为:有多少种不同的方式可以选择 a_1, a_2 ..a_n-1,每个数字不小于 0 并且它们的总和满足 a_1 + a_2 .... + a_(n-1) = 米?这个问题的答案是 n + m over n(我的意思是牛顿符号)。
为什么会这样?将此问题可视化为连续 n + m 个空箱。如果我们用沙子填充其中的 n 个,填充的距离将满足我们对 a_1 ... a_n-1 总和的要求。
一代
def generate(s, num_spaces):
ans = generate_aux("_" + s, num_spaces)
return [x[1:] for x in ans]
def generate_aux(s, num_spaces) : # returns list of arrangements
if num_spaces == 0:
return [s]
if s == "":
return []
val = []
for i in range(0, num_spaces + 1):
tmp = generate_aux(s[1:], num_spaces - i)
pref = s[0] + (" " * i)
val.extend([pref + x for x in tmp])
return val
print generate("abc", 2)
【讨论】:
是的,它有一个小错误:它适用于range(0, num_spaces + 1)
@phg:还有更多错误,但似乎符合 Wills 规范。以上是关于Python3 - 排列组合的迭代的主要内容,如果未能解决你的问题,请参考以下文章