C# 字符串生成器问题

C# 字符串生成器问题,c#,string,list,random,C#,String,List,Random,我想写一个返回字符串的方法。到现在为止,一直都还不错。然而,字符串的创建是相当复杂的。我有3个字符串列表-第一个有155个条目,第二个有9个条目,第三个有21个条目。我希望我的方法调用足够的次数(155*9*21)来返回3个列表中所有可能的值组合(基本上,这个方法应该计算调用的次数,每次只返回一个组合)。有没有办法做到这一点 我有155*9*22个可能的组合。第一次调用该方法时,应该使用List1(0)、List2(0)、List3(0)。在接下来的21次迭代中,第三个列表的索引只会发生变化。一

我想写一个返回字符串的方法。到现在为止,一直都还不错。然而,字符串的创建是相当复杂的。我有3个字符串列表-第一个有155个条目,第二个有9个条目,第三个有21个条目。我希望我的方法调用足够的次数(155*9*21)来返回3个列表中所有可能的值组合(基本上,这个方法应该计算调用的次数,每次只返回一个组合)。有没有办法做到这一点

我有155*9*22个可能的组合。第一次调用该方法时,应该使用List1(0)、List2(0)、List3(0)。在接下来的21次迭代中,第三个列表的索引只会发生变化。一旦使用了第三个列表中的所有元素,则增加第二个列表的索引,依此类推

一旦该方法产生了所有可能的组合(155*9*22),我希望它从头开始。

您可以列举所有可能的组合,如下所示:

    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
   }
public IEnumerable生成器(){
foreach(列表1中的字符串item1)
foreach(列表2中的字符串item2)
foreach(列表3中的字符串item3)
收益返回项1+2+3;
}
...
foreach(生成器()中的字符串项){
//对生成的字符串执行某些操作
}

您可以为每个列表保留索引:

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;
    }
}
public IEnumerable置换(字符串[][]列表,int start=0){
int[]位置=新int[lists.Length];
对于(int i=lists.Length-1;start>0;i--){
位置[i]=开始%s列表[i]。长度;
开始/=列表[i]。长度;
}
while(true){
int i;
string current=string.Empty;
对于(i=lists.Length-1;i>=0;i--){
if(++位置[i]==列表[i].长度){
位置[i]=0;
当前=列表[i][0]+当前;
}否则{
打破
}
}
如果(i==-1)中断;
而(i>-1){
当前=列表[i][position[i]]+当前;
我--;
}
产生回流电流;
}
}
它有一个起始位置(可选),因此您可以只保留一个整数并生成下一项

不过,我还没有测试过这个。小心点!:)

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

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

    return StringEnumerator.Current;
}

使用了很好的旧模运算符。可能可以进行更多的优化

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;
        }
    }
}
使用中显示的方法,可以跟踪您在列表中的位置:

// 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;
}
//使用他的生成器方法
公共IEnumerable生成器()
{
...
}
....
int计数器=0;
foreach(生成器()中的字符串项)
{
//计算索引
int ix_list3=计数器%list3.计数;
int ix_list2=(计数器/List3.Count)%list2.Count;
int ix_list1=(计数器/(List3.Count*List2.Count));
//对项目和索引做些什么
++计数器;
}

可能是您应该尝试的
收益回报
:简单到三个for循环;对于每个循环中的每个单词,打印输出结果是的,但是字符串的生成应该只在调用该方法时发生,我的目标是使用一些索引来保持我在同一方法中所取得的进展。@Andrey阅读了我在对您的问题的评论中发布的链接是的,这将返回所有可能的组合。然而,我希望我的方法只在被调用时进行计算,并计算它的运行情况。一种可能的方法是获取所有的组合并对它们进行索引,但如果我决定扩展该方法(添加一个列表),那么这将导致大量结果,这是不必要的内存使用。@Andrey:这不会生成单独的列表。它根据需要一次返回一个项目。这就是延迟执行的点(除其他外)。您可以使用我在答案中发布的技巧来跟踪计数。@Dmitry:如果您愿意,您可以将我的答案与您的答案结合起来,我将删除我的答案。一旦它涵盖了所有的组合,如何使它从第一个组合开始再次迭代?只需调用InitializeNumerator()再次,我修改了我的答案,加入了GetNextString的循环版本
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;
        }
    }
}
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
// 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;
}