目录
1.不重复取数的C(n,m)组合数
从集合中选择不重复元素的组合数可以用数学公式表示为:
C(n, m) = n! / (m!(n - m)!)
其中:
n! 表示 n 的阶乘,即 n × (n-1) × (n-2) × … × 3 × 2 × 1
m! 表示 m 的阶乘,即 m × (m-1) × (m-2) × … × 3 × 2 × 1
(n - m)! 表示 (n - m) 的阶乘,即 (n - m) × (n - m - 1) × (n - m - 2) × … × 3 × 2 × 1
C(n, m) 表示从 n 个不同的元素中选择 m 个元素的组合数。在这个公式中,我们通过计算所有可能的排列并去除重复的排列来得到不重复的组合数。
2.编程实现C(5, 3)不重复取数的组合并遍历输出
这个程序与作者的的可重复取数组合的程序类似,主要区别在于GenerateCombinations方法中的递归调用。在这个版本中,检查每个生成的组合是否包含当前的索引值。如果组合中不包含当前索引值,我们将其添加到结果中。这样,我们就可以确保生成的所有组合中的数字都是不重复的。
// 从n个数中选择m个数的不重复取数的所有组合
namespace _152_2
{
class Program
{
static void Main(string[] args)
{
ArgumentNullException.ThrowIfNull(args);
int n = 5; // 不重复的数的数量
int m = 3; // 需要选择的不重复数的数量
var combinations = GenerateCombinations(n, m).ToList();
Console.WriteLine("从n={0}个不重复的数中选择m={1}个不重复数的组合数为:{2}", n, m, combinations.Count);
Console.WriteLine("所有可能的组合:");
foreach (var combination in combinations)
{
Console.WriteLine(string.Join(", ", combination));
}
}
static IEnumerable<IEnumerable<int>> GenerateCombinations(int n, int m)
{
if (m == 0)
{
yield return Enumerable.Empty<int>();
}
else
{
for (int i = 0; i < n; i++)
{
foreach (var combination in GenerateCombinations(n, m - 1))
{
if (!combination.Contains(i))
{
yield return combination.Concat([i]);
}
}
}
}
}
}
}
//运行结果:
/*
从n=5个不重复的数中选择m=3个不重复数的组合数为:60
所有可能的组合:
2, 1, 0
3, 1, 0
4, 1, 0
1, 2, 0
3, 2, 0
4, 2, 0
1, 3, 0
2, 3, 0
4, 3, 0
1, 4, 0
2, 4, 0
3, 4, 0
2, 0, 1
3, 0, 1
4, 0, 1
0, 2, 1
3, 2, 1
4, 2, 1
0, 3, 1
2, 3, 1
4, 3, 1
0, 4, 1
2, 4, 1
3, 4, 1
1, 0, 2
3, 0, 2
4, 0, 2
0, 1, 2
3, 1, 2
4, 1, 2
0, 3, 2
1, 3, 2
4, 3, 2
0, 4, 2
1, 4, 2
3, 4, 2
1, 0, 3
2, 0, 3
4, 0, 3
0, 1, 3
2, 1, 3
4, 1, 3
0, 2, 3
1, 2, 3
4, 2, 3
0, 4, 3
1, 4, 3
2, 4, 3
1, 0, 4
2, 0, 4
3, 0, 4
0, 1, 4
2, 1, 4
3, 1, 4
0, 2, 4
1, 2, 4
3, 2, 4
0, 3, 4
1, 3, 4
2, 3, 4
*/