寻找不同的组合

时间:2012-10-02 22:11:14

标签: python

如何找到40个字母的所有组合?

我必须找到20 D和20 R可以制作多少组合。

在一个组合中可能是......

DDDDDDDDDDDDDDDDDDDDRRRRRRRRRRRRRRRRRRRR

那是1个组合,现在我怎么弄清楚剩下的?

5 个答案:

答案 0 :(得分:2)

要计算20 D和20 R的每个组合,我们可以想到有40个“插槽”,其中20个插槽将由D填充,其余的将由R填写。因此,我们可以使用C(40,20)或40选择20来计算combinations的总数,可以使用以下公式表示:

40!/(20!*(40-20)!)

或者在Python中:

>>> import math
>>> math.factorial(40) / (math.factorial(20) * math.factorial(40-20))
137846528820L

请注意,这与20 D和20 R字符串的 唯一 排列数相同,但如果你只计算那个字符串的排列数,你将计算很多重复项,如果你试图通过创建每个排列来计算它,那将需要很长时间。

如果你想实际生成唯一的排列(我不建议),一种方法是使用itertools.combinations(range(40), 20)。这里返回的每个元素都是20个整数的元组,它们是该特定排列中每个D的索引。

答案 1 :(得分:1)

有很多排列。生成它们通常不是一个好主意,只是为了计算它们。您应该寻找一个数学公式来解决这个问题,或者使用动态编程来计算结果。

答案 2 :(得分:0)

这是一个内置于itertools中的一个很好的函数:

直接来自此链接:9.7. itertools — Functions creating iterators for efficient looping

def permutations(iterable, r=None):
    # permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC
    # permutations(range(3)) --> 012 021 102 120 201 210
    pool = tuple(iterable)
    n = len(pool)
    r = n if r is None else r
    if r > n:
        return
    indices = range(n)
    cycles = range(n, n-r, -1)
    yield tuple(pool[i] for i in indices[:r])
    while n:
        for i in reversed(range(r)):
            cycles[i] -= 1
            if cycles[i] == 0:
                indices[i:] = indices[i+1:] + indices[i:i+1]
                cycles[i] = n - i
            else:
                j = cycles[i]
                indices[i], indices[-j] = indices[-j], indices[i]
                yield tuple(pool[i] for i in indices[:r])
                break
        else:
            return

修改

我添加了一个我在SO上找到的链接,它提供了使用JavaScript执行此操作的一个很好的示例:Is there any pre-built method for finding all permutations of a given string in JavaScript?

如果你不介意PHP,这里有一个直接来自这个链接的例子:4.26. Finding All Permutations of an Array

注意:要使用pc_permute函数,您需要将字符串分隔为字符数组。

function pc_permute($items, $perms = array( )) {
    if (empty($items)) { 
        print join(' ', $perms) . "\n";
    }  else {
        for ($i = count($items) - 1; $i >= 0; --$i) {
             $newitems = $items;
             $newperms = $perms;
             list($foo) = array_splice($newitems, $i, 1);
             array_unshift($newperms, $foo);
             pc_permute($newitems, $newperms);
         }
    }
}

答案 3 :(得分:0)

根据您对组合的要求,有很多方法可以解决这个问题。如果您只想知道存在的组合/排列的数量,数学可以告诉您。

如果你想做一些像构建强力算法来检查给定字符集的每个可能排列的东西,itertools.product()可以提供帮助。

http://docs.python.org/library/itertools.html#module-itertools

答案 4 :(得分:0)

这是一个生成所有不同排列的生成器。

def distinct_pem(A,D):
    if A==0: yield 'D'*D
    elif D==0: yield 'A'*A
    elif A==1 and D==1:
        yield 'AD'
        yield 'DA'
    else:
        if A>=2:
            for string in distinct_pem(A-2,D):
                yield  'AA'+string
        if A>1 and D>1:
            for string in distinct_pem(A-1,D-1):
                yield  'AD'+string
                yield  'DA'+string
        if D>=2:
            for string in distinct_pem(A,D-2):
                yield  'DD'+string

对于10这个速度非常快,但是它很难用20(也许它可以提高效率?)。