2

重複の可能性:
配列のさまざまな組み合わせ(C#)

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

組み合わせ式nCr=10!/ 2!(10-2)!を使用して、組み合わせごとに2/3/4/5の文字列を生成する方法。たとえば、組み合わせごとに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の組み合わせになります。

どうすればそれを書くことができますか?私は多くのループを使い果たしました、そしてそれは本当に混乱に見えます。

4

3 に答える 3

9

単純な再帰を使用できます。

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);
于 2012-12-04T09:25:48.347 に答える
7

この効率的なプロジェクトを使用できます: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
于 2012-12-04T09:04:56.970 に答える
-1

これは、nCrを使用して2つの数値の組み合わせを実行する関数です。複数の数値に対して微調整します。

    /// <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;
    }
于 2012-12-04T09:05:21.360 に答える