-2

我想写一个返回字符串的方法。到目前为止,一切都很好。然而,字符串的创建相当复杂。我有 3 个字符串列表 - 第一个有 155 个条目,第二个有 9 个,第三个有 21 个。我希望我的方法调用足够多的次数(155*9*21)来返回 3 中所有可能的值组合列表(基本上这个方法应该计算它被调用的次数并且每次只返回一个组合)。任何想法如何做到这一点?

我有 155*9*22 种可能的组合。第一次调用该方法时,它应该采用 List1(0)、List2(0)、List3(0)。之后在接下来的 21 次迭代中,仅更改了第三个列表的索引。一旦第三个列表中的所有元素都被使用,第二个列表的索引就会增加,依此类推。

一旦该方法产生了所有可能的组合 (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 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;
    }
}

可选地,它需要一个开始的地方,因此您可以只保留一个整数并生成下一个项目。

不过,我还没有测试过。被警告!:)

于 2013-06-26T16:06:41.613 回答
1
public IEnumerable<string> List1 = new [] { "A", "B", "C" };
public IEnumerable<string> List2 = new [] { "1", "2", "3" };
public IEnumerable<string> List3 = new [] { "Z", "Y" };

public IEnumerator<string> StringEnumerator;

public void InitializeEnumerator()
{
    var stringEnumerable = List1.SelectMany(x => List2.SelectMany(y => List3.Select(z => x + y + z)));

    StringEnumerator = stringEnumerable.GetEnumerator();
}

public string GetNextString()
{
    return StringEnumerator.MoveNext() ? StringEnumerator.Current : null;
}

只需调用 InitializeEnumerator(),然后每次调用 GetNextString() 都会得到一个新字符串

InitializeEnumerator();
GetNextString(); //-> A1Z
GetNextString(); //-> A1Y
GetNextString(); //-> A2Z
GetNextString(); //-> A2Y
GetNextString(); //-> A3Z
GetNextString(); //-> A3Y
GetNextString(); //-> B1Z

要让它在用完后自动初始化并重新初始化,请像这样修改 GetNextString。

public string GetNextString()
{
    if(StringEnumerator == null || !StringEnumerator.MoveNext())
    {
        InitializeEnumerator();
        StringEnumerator.MoveNext();
    }

    return StringEnumerator.Current;
}
于 2013-06-26T16:11:35.593 回答
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 回答
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 回答