使用c#中的字符串数组生成组合

时间:2012-12-04 08:50:13

标签: c# arrays algorithm combinations

  

可能重复:
  Different combinations of an array (C#)

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个组合。

我该怎么写?我已经用完了许多循环,看起来真的很乱。

3 个答案:

答案 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;
    }