Algorithm 寻找一种通用的、快速的、低内存的算法来输出一个数组的N-of-M组合而无需重复

Algorithm 寻找一种通用的、快速的、低内存的算法来输出一个数组的N-of-M组合而无需重复,algorithm,combinations,Algorithm,Combinations,我有一个玩家阵列 $players = array('A','B','C','D','E','F'); 我想让每一个可能的三方完成 1st 2nd 3rd A B C A B D ... C A B C B A ... F D E F E D 我有一些排列算法,但它一定是别的,因为在排列中有6*5*4*3*2*1组合,这里只有6*5*4,你的问题不是找到6个元素的所有排列 您的问题是选择3个元素,然后检查其排列 组合数=C(6,3)*3!=6!

我有一个玩家阵列

$players = array('A','B','C','D','E','F');
我想让每一个可能的三方完成

1st 2nd 3rd
A   B   C
A   B   D
...
C   A   B
C   B   A
...
F   D   E
F   E   D

我有一些排列算法,但它一定是别的,因为在排列中有6*5*4*3*2*1组合,这里只有6*5*4,你的问题不是找到6个元素的所有排列

您的问题是选择3个元素,然后检查其排列

组合数=C(6,3)*3!=6! / 3! = 6*5*4

C(6,3)-用于从6个元素中选择3个元素。(无论命令如何)

3!-用于对3个选定元素进行排序

这正是您应该获得的组合数。(你也是)

但是,您可以使用排列算法来获得6个元素的所有排列。
然后,忽略最后3个元素,并从结果中删除重复项。

我可能错了,但我认为您在这里有正确数量的可能排列。您只能在6名玩家阵列中选择3名玩家。第一个玩家有6种可能性,第二个玩家有5种可能性,第三个玩家有4种可能性

如果你决定在最后有4个玩家而不是3个,那么可能的排列数量将是6*5*4*3,依此类推


我希望我的数学不会太老

给定您的排列算法,您可以分两步使用它来获得所需的排列

首先,我们考虑下面的映射。给定输入为
A1 A2 A3 A4 A5。。。一个
,一个值b1 b2 b3 b4 b5。。。bn表示如果
bi
为1,则选择
Ai
,如果为0,则不选择

使用您的输入,例如:

0 0 1 1 0 1 -> C D F
0 1 0 0 1 1 -> B E F
现在,您的算法可以如下所示:

  • n
    作为元素的数量(在您的案例中为6),将
    m
    作为您要选择的数量
  • 构建以下序列:

    0 0 0 ... 0 1 1 1 ... 1
    \____ ____/ \____ ____/
         V           V
       n - m         m
    
  • 获取上述序列的所有排列,并针对每个排列:

    • 查找序列中标记的
      m
      元素
    • 获取这些
      m
      元素的所有排列,并针对每个元素:
      • 你想干什么就干什么

以下是一些伪代码,可以不重复地打印6个组合中的3个:

for i = 1 to 6
  for j = 1 to 6
    if (j != i)
      for k = 1 to 6
        if (k != i && k != j)
          print(A[i], A[j], A[k])
        end if
      next k
    end if
  next j
next i

对于一般的k-of-n情况,请参见:

您说您有一些排列算法。如果你想得到帮助,我建议你发布代码。代码的答案是6*5*4,因为其他地方都不重要。你们知道他想要的是排列,而不仅仅是计数,对吧?!如果他想要七分之四呢?还是五分之二?还是10分之5?还是四分之一?还是六分之六?还是八分之三?还是四分之二?还是八分之六?或者五分之四?只需调整代码即可。伪代码只解决给定的问题。没有更多,也没有更少。我的意思是,即使这解决了具体问题,但它根本无法扩展,在其他情况下也无法重复使用。我完全同意。但为什么要解决可能根本不存在的问题呢?将6更改为数组长度应该不是问题。问题很清楚,他只需要N名中的3名(比赛前3名)。否则,他可能会问一个更一般的问题:“寻找一种通用、快速、低内存占用率的算法,在不重复的情况下输出数组的M中N个组合”。;-)他似乎听了你的建议;)我不是100%确定,但当我发现我想要的是组合而不是排列时,在你的例子中,
abc
cab
是有区别的。这是排列。如果你只需要3个,不管它们的顺序(组合),那么你必须跳过内部<代码> GETX置换< /C>。C++已经存在。它被称为