确定可能的组合数量

时间:2010-01-04 05:11:20

标签: python math statistics combinatorics

我正在试图弄清楚有多少种方法可以将各种元素组合成这个字符串。

"{Hello|Hi|Hey} {world|earth}{!|.|?}"

从每个组({})中随机选择一个项目(由管道/ |分隔)并组合成一个字符串。

所以上面的“模板”可以产生:

Hello world.
Hi earth?
Hey world.
Hi world?

我猜这是一种排列,但我想确保我做对了。

如果这也适用于“n”嵌套项目,那将是非常好的。

"{{Hello|Hi|Hey} {world|earth}|{Goodbye|farewell} {noobs|n3wbz|n00blets}}"

如果可能的话,我更喜欢基于数学/统计的解决方案而不是暴力循环来获得答案。

谢谢!

2 个答案:

答案 0 :(得分:6)

嗯,你的第一个例子中有3 x 2 x 3 = 18种组合。

你的第二个例子是3 x 4 x 2 x 3 = 72种组合。

我不完全确定{a|b}|{c|d}你的意思,我假设你的意思是选择(a或b)或(c或d)中的一个,这是4个选择。

您可能希望了解合并herehere


更新:是的,就这么简单。您的问题与计算数字中的数字组合的数量完全相同。例如,如果我想查找ATM PIN号码组合的数量(4位十进制数字),我设置{0-9},{0-9},{0-9},{0-9}。第一种选择(= 10)有10种可能性。对于这些数字中的每一个,第二选择有10种可能性(= 10×10)。对于每一个,第三个(= 10×10×10)为10,第四个为10(= 10×10×10×10 = 10,000)。应该直观地清楚,4位十进制数有10,000种可能性。

您的示例使用的是单词集而不是数字集,但原理是相同的。组合数量是集合1中的项目数量×集合中的项目数量2×...×集合n中的项目数量等。

当您开始设置限制或从同一组中挑选多个项目时,它会变得更加复杂。

答案 1 :(得分:0)

问题分解为两个简单的子问题:

  1. 计算每个大括号对中大括号内的多少个组合以及在vbars中分隔的组合
  2. 乘以这些数字
  3. 因此对于1我会使用简单的正则表达式+循环方法:

    import re
    
    def docount(thestring):
        x = re.compile(r'{([^}]}')
        counts = [mo.group(0).count('|')+1 for mo in x.finditer(thestring)]
        result = 1
        for c in counts: result *= c
        return result
    

    我已经嵌入2,因为这是最无聊的部分(如果你热衷于将reduce用于此类目的,那也可以代替最后三行,我猜测;。 - )