string[] array = {"01", "02", "03", "04", "05", "06", "07", "08", "09", "10"};
如何为每个组合生成2/3/4/5字符串,例如每个组合2个字符串,没有重复/重复,也忽略位置,使用组合公式nCr = 10!/ 2!(10- 2)! = 45种组合。
我需要输出如下:
"01", "02"
"01", "03"
"01", "04"
...
"02", "03" // eliminate the "02","01" 'cause it is same as "01","02" combination
"02", "04"
...
然后生成3个字符串的组合,将有120个组合(根据nCr)。 我需要输出如下:
"01","02","03"
"01","02","04"
...
4个字符串的组合,将有210个组合,最少,每个组合5个字符串的组合,将有252个组合。
我该怎么写?我已经用完了许多循环,看起来真的很乱。
答案 0 :(得分:8)
您可以使用简单的递归:
private static IEnumerable<string> Combinations(int start, int level)
{
for ( int i = start; i < array.Length; i++ )
if ( level == 1 )
yield return array[i];
else
foreach ( string combination in Combinations(i + 1, level - 1) )
yield return String.Format("{0} {1}", array[i], combination);
}
这样称呼:
var combinations = Combinations(0, 2);
foreach ( var item in combinations )
Console.WriteLine(item);
答案 1 :(得分:6)
您可以使用此高效项目:Permutations, Combinations, and Variations using C# Generics。
string[] array = { "01", "02", "03", "04", "05", "06", "07", "08", "09", "10" };
int lowerIndex = 2;
var combinations = new Facet.Combinatorics.Combinations<String>(
array,
lowerIndex,
Facet.Combinatorics.GenerateOption.WithoutRepetition
);
foreach (IList<String> combis in combinations)
{
String combi = String.Join(" ", combis);
Console.WriteLine(combi);
}
由于它是开源的,你可以看看它是如何实现的。但上面的链接也非常有用。
输出(lowerIndex = 2):
01 02
01 03
01 04
01 05
01 06
01 07
01 08
01 09
01 10
02 03 <-- no 02 01 since it would be a repitition
02 04
02 05
// ... (45 combinations w/o repetitions)
09 10
输出(lowerIndex = 5):
01 02 03 04 05
01 02 03 04 06
01 02 03 04 07
01 02 03 04 08
01 02 03 04 09
01 02 03 04 10
01 02 03 05 06
01 02 03 05 07
01 02 03 05 08
01 02 03 05 09
01 02 03 05 10
01 02 03 06 07
// ........... (252 combinations w/o repetitions)
05 07 08 09 10
06 07 08 09 10
答案 2 :(得分:-1)
以下是使用nCr对两个数字执行组合的功能,将其调整为多个数字
/// <summary>
/// Performs a nCr Combination of the two numbers
/// </summary>
/// <param name="n">The Number</param>
/// <param name="r">The Range</param>
/// <returns></returns>
public static double Combination(double n, double r)
{
/*
* Formula for Combination: n! / (r! * (n - r)!)
*/
// n and r should be integral values
double rfloor = Math.Floor(r);
double nfloor = Math.Floor(n);
// Check for all invalid values of n and r.
if ((n < 1) || (r < 0) || (r > n) || (r != rfloor) || (n != nfloor))
{
throw new Exception("Invalid Input to Combination Function: Number must be greater than Range");
}
return Factorial(n) / (Factorial(r) * Factorial(n - r));
}
和
public static double Factorial(double n)
{
if (n < 0) { throw new Exception("Cannot take the factorial of a negative number"); }
double factorial = 1;
// 0! and 1! = 1
for (double i = 2; i < n + 1; i++)
{
factorial *= i;
}
return factorial;
}