-2

文字列を返すメソッドを書きたいです。ここまでは順調ですね。ただし、文字列の作成は非常に複雑です。3 つの文字列リストがあります。最初のリストには 155 のエントリがあり、2 番目のリストには 9、3 番目のリストには 21 があります。メソッドが十分な回数 (155*9*21) 呼び出されて、3 つの値のすべての可能な組み合わせを返すようにしたいです。リスト (基本的に、このメソッドは呼び出された回数をカウントし、毎回 1 つの組み合わせのみを返す必要があります)。それを達成する方法はありますか?

155*9*22 の可能な組み合わせがあります。メソッドが初めて呼び出されるときは、List1(0)、List2(0)、List3(0) を受け取る必要があります。その後、次の 21 回の反復では、3 番目のリストのインデックスのみが変更されます。3 番目のリストのすべての要素が使用されると、2 番目のリストのインデックスがインクリメントされます。

メソッドがすべての可能な組み合わせ (155*9*22) を生成したら、最初から開始したいと思います。

4

5 に答える 5

3

次のように、考えられるすべての組み合わせを列挙できます。

    public IEnumerable<String> generator() {
      foreach (String item1 in List1)
        foreach (String item2 in List2)
          foreach (String item3 in List3)
            yield return item1 + item2 + item3;
    }

   ...

   foreach (String item in generator()) {
     // Do something with generated strings
   }
于 2013-06-26T15:53:25.173 に答える
1

古き良きモジュロ演算子を使用しました。おそらくもっと最適化できます。

public class Generator
{
    private int index = 0;
    private List<string> list1 = new List<string> { "a", "b" };
    private List<string> list2 = new List<string> { "c", "d" };
    private List<string> list3 = new List<string> { "e", "f", "g" };

    public string Next()
    {
        int indexList3 = index % list3.Count;
        int indexList2 = (index / list3.Count) % list2.Count;
        int indexList1 = (index / (list2.Count * list3.Count)) % list1.Count;

        IncrementIndex();

        return list1[indexList1] + list2[indexList2] + list3[indexList3];
    }

    private void IncrementIndex()
    {
        index++;
        if (index > list1.Count*list2.Count*list3.Count)
        {
            index = 0;
        }
    }
}

したがって、最初の 13 の結果 (12 の可能な組み合わせ) で得られた

string result = string.Empty;
Generator generator = new Generator();

for (int i = 0; i < 13; i++)
{
    result += generator.Next() + "\n";
}

出力:

ace
acf
acg
ade
adf
adg
bce
bcf
bcg
bde
bdf
bdg
ace
于 2013-06-26T16:14:15.220 に答える
1

各リストのインデックスを保持できます。

public IEnumerable<string> Permutations(string[][] lists, int start = 0) {
    int[] position = new int[lists.Length];

    for(int i = lists.Length - 1; start > 0; i--) {
        position[i] = start % lists[i].Length;
        start /= lists[i].Length;
    }

    while(true) {
        int i;
        string current = string.Empty;

        for(i = lists.Length - 1; i >= 0; i--) {
            if(++position[i] == lists[i].Length) {
                position[i] = 0;
                current = lists[i][0] + current;
            } else {
                break;
            }
        }

        if(i == -1) break;

        while(i > -1) {
            current = lists[i][position[i]] + current;
            i--;
        }

        yield return current;
    }
}

オプションで開始する場所を取るため、整数を 1 つだけ保持して次のアイテムを生成できます。

ただし、これはテストしていません。注意してください!:)

于 2013-06-26T16:06:41.613 に答える
1

Dmitry Bychenkoが示した方法を使用すると、リスト内のどこまで進んでいるかを追跡できます。

// use his generator method
public IEnumerable<String> generator()
{
    ...
}

....

int counter = 0;
foreach (String item in generator())
{
    // compute indexes
    int ix_list3 = counter % List3.Count;
    int ix_list2 = (counter / List3.Count) % List2.Count;
    int ix_list1 = (counter / (List3.Count * List2.Count));

    // do something with item and indexes
    ++counter;
}
于 2013-06-26T16:16:40.523 に答える