C# 从一组x项中随机选择n项的所有可能组合(算法)
我有一组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++]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
谢谢您的帮助。从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])
或者,您可以使用滑动窗口技巧来执行某些操作
此外,我认为该公式效果更好,除非值太大。斯特林公式也很有用。