如何写出所有可能的组合
How to write all possible combinations
为了更好的理解,我举一个简单的例子:
我们有 10 盏灯。我们可以点亮一两个。需要写下点亮两盏灯的所有方法。这个例子很简单。我们可以像这样列出所有选项:
List<string> lstAllOptions = new List<string> ( );
for ( int i = 1; i <= 10; i++ )
{
lstAllOptions.Add ( i.ToString ( ) );
}
for ( int i = 1; i <= 10; i++ )
{
for ( int j = 1; j <= 10; j++ )
{
if ( i != j && j>i )
{
lstAllOptions.Add ( i.ToString ( ) + " and " + j.ToString ( ) );
}
}
}
但是如果用户设置了灯的数量呢?我们可以有 43 盏灯,并且可以打开其中的 19 盏。或者随心所欲。我可以增加For的数量,但是很难。如何更简单地解决这个问题,并为任意数量的灯做一个通用的方法?
计算这种组合的方法如下:
public static IEnumerable<IEnumerable<int>> AllCombinations(int n, int k) =>
from i in Enumerable.Range(0, 1 << n)
let r = Enumerable.Range(0, n).Select(j => ((i & 1 << j) == 0 ? 1 : 0))
where r.Count(s => s == 1) <= k
select r;
然而,对于 n == 43
,它吹拍了整数可以容纳的东西。
它确实适用于较低的值:
Console.WriteLine(AllCombinations(24, 19).Count());
给出:
16764265
为了更好的理解,我举一个简单的例子: 我们有 10 盏灯。我们可以点亮一两个。需要写下点亮两盏灯的所有方法。这个例子很简单。我们可以像这样列出所有选项:
List<string> lstAllOptions = new List<string> ( );
for ( int i = 1; i <= 10; i++ )
{
lstAllOptions.Add ( i.ToString ( ) );
}
for ( int i = 1; i <= 10; i++ )
{
for ( int j = 1; j <= 10; j++ )
{
if ( i != j && j>i )
{
lstAllOptions.Add ( i.ToString ( ) + " and " + j.ToString ( ) );
}
}
}
但是如果用户设置了灯的数量呢?我们可以有 43 盏灯,并且可以打开其中的 19 盏。或者随心所欲。我可以增加For的数量,但是很难。如何更简单地解决这个问题,并为任意数量的灯做一个通用的方法?
计算这种组合的方法如下:
public static IEnumerable<IEnumerable<int>> AllCombinations(int n, int k) =>
from i in Enumerable.Range(0, 1 << n)
let r = Enumerable.Range(0, n).Select(j => ((i & 1 << j) == 0 ? 1 : 0))
where r.Count(s => s == 1) <= k
select r;
然而,对于 n == 43
,它吹拍了整数可以容纳的东西。
它确实适用于较低的值:
Console.WriteLine(AllCombinations(24, 19).Count());
给出:
16764265