C# 从一组x项中随机选择n项的所有可能组合(算法)

C# 从一组x项中随机选择n项的所有可能组合(算法),c#,c++,algorithm,combinations,C#,C++,Algorithm,Combinations,我有一组x字符串项e.gA,B,C,D,e,F 我需要知道计算n个项目组合数量的公式,以及生成所有可能组合的算法 例如 如果我们需要从列表中随机选择4项。 这4个项目可以是: A、 B、C、D或 A、 B、C、E或 A、 B、C、F或 A、 B、D、E……等 我需要一个公式来计算没有重复的多个项目集,也就是说,我们把A、B、C、D看作是一个结果组合,我们不能考虑与另一个结果组合相同的项目,用替换A、B、D、C中集合中的项目的位置。 此外,我需要的算法,生成所有可能的组合在任何编程语言。[C,VB

我有一组x字符串项e.gA,B,C,D,e,F 我需要知道计算n个项目组合数量的公式,以及生成所有可能组合的算法 例如 如果我们需要从列表中随机选择4项。 这4个项目可以是: A、 B、C、D或 A、 B、C、E或 A、 B、C、F或 A、 B、D、E……等 我需要一个公式来计算没有重复的多个项目集,也就是说,我们把A、B、C、D看作是一个结果组合,我们不能考虑与另一个结果组合相同的项目,用替换A、B、D、C中集合中的项目的位置。 此外,我需要的算法,生成所有可能的组合在任何编程语言。[C,VB.NET,Java,C++]


谢谢您的帮助。

从n个项目中选择p,这是一个公式,可以告诉您有多少个组合

                  n!
n choose p  = -----------
               p! (n-p)!
谷歌计算器将为您计算:

6选择4=15

你需要二项式定理,你需要嵌套循环。至于用一种编程语言实现,编写起来并不太困难。如果你环顾四周,你会发现这个问题经常被问到,你会发现有人因为这个原因投票结束你的问题。

你也可以选择

大概是这样的:

#include <stdio.h>

void print(const int *v, const int size)
{
    int i;
    if (v != 0) {
        for (i = 0; i < size; i++) {
            printf("%4d", v[i] );
        }
        printf("\n");
    }
} // print


void visit(int *Value, int N, int k)
{
    int i;
    static level = -1;
    level = level+1; Value[k] = level;

    if (level == N)
        print(Value, N);
    else
        for (i = 0; i < N; i++)
            if (Value[i] == 0)
                visit(Value, N, i);

    level = level-1; Value[k] = 0;
}


main()
{
    const int N = 4;
    int Value[N];
    int i;
    for (i = 0; i < N; i++) {
        Value[i] = 0;
    }
    visit(Value, N, 0);
}

您可以使用计算组合的数量。要找到实际的组合,可以使用简单的递归。

组合的公式,即您所描述的,在@Mark Harrison的答案中给出。然而,插入这个等式,它就会爆炸,因为数学是用来抵消的

例如,50选择49-这与选择要排除的元素相同,因此有50个选择。但是,该公式需要您进行计算

   50!       3.04140932e64
-------- = ----------------- = 50
1! * 49!   1 * 6.08281864e62
你真正想要的x选择y的等式是

x * (x-1) * ... * (x-n+1)
-------------------------
n * (n-1) * ... * 2 * 1
一些简单的C代码[注意,这优化了Cx,y=Cx,x-y-这应该很容易从组合公式中看出]:

int c(int x, int y)
{
    int num = 1, denom = 1;
    int i;
    if (y > x-y)
        y = x - y;
    for (i = 0; i < y; ++i)
    {
        num *= (x - i);
        denom *= (y - i);
    }
    return num/denom;
}
所以,如果你想要所有可能的字母组合ABCDEF,你可以选择4个字母,也就是c6,4

我需要在任何编程语言中生成所有可能组合的算法

好的,这里有一个Haskell中的单线解决方案:

import Data.List (subsequences)

n `outOf` xs = filter ((n ==) . length) (subsequences xs)

test = 4 `outOf` ["A", "B", "C", "D", "E", "F"]

*Main> test
[["A","B","C","D"],["A","B","C","E"],["A","B","D","E"],["A","C","D","E"],["B","C
","D","E"],["A","B","C","F"],["A","B","D","F"],["A","C","D","F"],["B","C","D","F
"],["A","B","E","F"],["A","C","E","F"],["B","C","E","F"],["A","D","E","F"],["B",
"D","E","F"],["C","D","E","F"]]
*Main> length test
15

是的,帕斯卡的三角形很管用


int dp[MAX_X][MAX_Y] = {0};

dp[0][0] = 1;
for (int i = 1; i <= X; i++) {
    dp[i][0] = dp[i][i] = 0;
    for (int j = 1; j < min(i, Y + 1); j++)
        dp[i][j] = dp[i-1][j] + dp[i-1][j-1];
}

print(dp[X][Y])
或者,您可以使用滑动窗口技巧来执行某些操作


此外,我认为该公式效果更好,除非值太大。

斯特林公式也很有用。