2

Possible Duplicate:
Different combinations of an array (C#)

string[] array = {"01", "02", "03", "04", "05", "06", "07", "08", "09", "10"};

How to generate to 2 / 3 / 4 / 5 strings per combination like for example 2 strings per combination, with no repeats/duplicates, disregard of position as well, using combination formula nCr = 10!/2!(10-2)! = 45 combinations.

I need the output to be like this:

"01", "02"
"01", "03"
"01", "04"
...
"02", "03" // eliminate the "02","01" 'cause it is same as "01","02" combination
"02", "04"
...

Then to generate combinations of 3 strings, would have 120 combinations (according to nCr). I need the output to be like this:

"01","02","03"
"01","02","04"
...

And combinations of 4 strings, would have 210 combinations, the least, combinations of 5 strings per combination, would have 252 combinations.

How can I write that? I've used up many loops and it looks really a mess.

Community
  • 1
  • 1

3 Answers3

9

You could use a simple recursion:

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);
}

The call it like this:

  var combinations = Combinations(0, 2);

  foreach ( var item in combinations )
    Console.WriteLine(item);
Adam Kostecki
  • 301
  • 1
  • 3
7

You can use this efficient project: 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);
}

Since it's open source you can look how it's implemented. But the link above is also very informative.

output (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

output (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
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • how can I use "Facet" in code? Need a particular namespace / library? – Renise Sachiko Dec 04 '12 at 09:12
  • Yes of course. The [**link**](http://www.codeproject.com/Articles/26050/Permutations-Combinations-and-Variations-using-C-G) i've provided contains also two download links(at the top). One for a demo program and the other for the source. – Tim Schmelter Dec 04 '12 at 09:18
-1

Here is the function to perform combinations for two numbers using nCr,Tweak it for multiple numbers

    /// <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));
    }

And

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;
    }
sajanyamaha
  • 3,119
  • 2
  • 26
  • 44