2

ページには、動的に作成される 5 つのカスケード コンボ ボックスがあります。希望の金額が達成されたら、何かをしなければなりません。これは、出力を生成する私のコードです。すべての for ループ、さらにはすべての 'cmb' 配列を動的に生成したいと考えています。どうすれば達成できますか?

private int[] cmb1 = { 0, 2, 4, 6, 8, 12, 16, 20 };
private int[] cmb2 = { 0, 2, 4, 6, 8, 12, 16, 20 };
private int[] cmb3 = { 0, 2, 4, 6, 8, 12, 16, 20 };
private int[] cmb4 = { 0, 2, 4, 6, 8, 12, 16, 20 };
private int[] cmb5 = { 0, 2, 4, 6, 8, 12, 16, 20 };
int count = 0;

        for (int i = 0; i < cmb1.Length; i++)
        {
            for (int j = 0; j < cmb2.Length; j++)
            {
                for (int k = 0; k < cmb3.Length; k++)
                {
                    for (int l = 0; l < cmb4.Length; l++)
                    {
                        for (int m = 0; m < cmb5.Length; m++)
                        {
                            if (cmb1[i] + cmb2[j] + cmb3[k] + cmb4[l] + cmb5[m] <= 20 && (i + j + k + l + m) != 0)
                            {
                                Console.WriteLine(count + " _ " + i + " " + j + " " + k + " " + l + " " + m);
                                count = count + 1;
                            }

                        }
                    }
                }
            }
        }
4

2 に答える 2

3

あなたがしようとしていることは、(コンパイル時に)不明な数のシーケンスのデカルト積と見なすことができます。

Eric Lippert は、C# でこのようなソリューションを作成する方法についてのブログ投稿を書きました。彼が最終的に生成するコードは次のとおりです。

public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences)
{
    IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() };
    return sequences.Aggregate(
        emptyProduct,
        (accumulator, sequence) =>
        from accseq in accumulator
        from item in sequence
        select accseq.Concat(new[] { item }));
}

これを使用して、次のことができます。

List<int[]> cmbs = new List<int[]>();
cmbs.Add(new int[] { 0, 2, 4, 6, 8, 12, 16, 20 });
cmbs.Add(new int[] { 0, 2, 4, 6, 8, 12, 16, 20 });
cmbs.Add(new int[] { 0, 2, 4, 6, 8, 12, 16, 20 });

var query = cmbs.CartesianProduct()
    .Where(combo => combo.Sum() <= 20 && combo.Sum() > 0);

int count = 0;
foreach (var combo in query)
{
    Console.Write((count++) + " _ ");
    Console.WriteLine(string.Join(" ", combo));
}
于 2013-08-20T15:29:18.923 に答える
1

Linq でのデカルト積の実装に関する Eric Lippert の優れた記事を紹介します。これは、彼が一般的な拡張メソッドとして書いたものです。

static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences) 
{ 
    // base case: 
    IEnumerable<IEnumerable<T>> result = new[] { Enumerable.Empty<T>() }; 
    foreach(var sequence in sequences) 
    { 
        var s = sequence; // don't close over the loop variable 
        // recursive case: use SelectMany to build the new product out of the old one 
        result = 
          from seq in result 
          from item in s 
          select seq.Concat(new[] {item}); 
    } 

    return result; 
}

したがって、コードでは次のように呼び出します。

private List<int[]> cmbs = new List<int[]>();

...

// build cmbs list
cmbs.Add(cmb1);
cmbs.Add(cmb2);
cmbs.Add(cmb3);
cmbs.Add(cmb4);
cmbs.Add(cmb5);

// loop through cmbs
var count = 0;
foreach(var result in cmbs.CartesianProduct().Skip(1)) // Skip the first result
{
    if (result.Sum() <= 20) 
    {
        Console.WriteLine(count + "_" + String.Join(" ", result));
        count = count + 1;
    }
}
于 2013-08-20T15:29:07.487 に答える