Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无显式枚举数的递归生成器_C#_Generator_Yield Return_Ienumerator - Fatal编程技术网

C# 无显式枚举数的递归生成器

C# 无显式枚举数的递归生成器,c#,generator,yield-return,ienumerator,C#,Generator,Yield Return,Ienumerator,下面是一个使用显式枚举数的生成器: static IEnumerable<string> generate(string s) { yield return new Regex("e").Replace(s, "", 1); yield return new Regex("aaaa").Replace(s, "e", 1); yield return new Regex("aa").Replace(s, "bb", 1); yield return

下面是一个使用显式枚举数的生成器:

static IEnumerable<string> generate(string s)
{
    yield return new Regex("e").Replace(s, "", 1);

    yield return new Regex("aaaa").Replace(s, "e", 1);
    yield return new Regex("aa").Replace(s, "bb", 1);
    yield return new Regex("ba").Replace(s, "abbb", 1);

    yield return new Regex("bb").Replace(s, "aa", 1);

    var en0 = generate(new Regex("e").Replace(s, "", 1)).GetEnumerator();
    var en1 = generate(new Regex("aaaa").Replace(s, "e", 1)).GetEnumerator();
    var en2 = generate(new Regex("aa").Replace(s, "bb", 1)).GetEnumerator();
    var en3 = generate(new Regex("ba").Replace(s, "abbb", 1)).GetEnumerator();
    var en4 = generate(new Regex("bb").Replace(s, "aa", 1)).GetEnumerator();

    while(true)
    {
        en0.MoveNext(); yield return en0.Current;
        en1.MoveNext(); yield return en1.Current;
        en2.MoveNext(); yield return en2.Current;
        en3.MoveNext(); yield return en3.Current;
        en4.MoveNext(); yield return en4.Current;
    }
}
显示表格:


在上面的评论中,Rob提到一种方法是使用
Zip

下面是使用
Zip
生成
的一个版本:

static IEnumerable<string> generate(string s)
{
    yield return new Regex("e").Replace(s, "", 1);

    yield return new Regex("aaaa").Replace(s, "e", 1);
    yield return new Regex("aa").Replace(s, "bb", 1);
    yield return new Regex("ba").Replace(s, "abbb", 1);

    yield return new Regex("bb").Replace(s, "aa", 1);

    var seq =
        generate(new Regex("e").Replace(s, "", 1))
            .Zip(generate(new Regex("aaaa").Replace(s, "e", 1)), (a, b) => new { a = a, b = b }).SelectMany(elt => new[] { elt.a, elt.b })
            .Zip(generate(new Regex("aa").Replace(s, "bb", 1)), (a, b) => new { a = a, b = b }).SelectMany(elt => new[] { elt.a, elt.b })
            .Zip(generate(new Regex("ba").Replace(s, "abbb", 1)), (a, b) => new { a = a, b = b }).SelectMany(elt => new[] { elt.a, elt.b })
            .Zip(generate(new Regex("bb").Replace(s, "aa", 1)), (a, b) => new { a = a, b = b }).SelectMany(elt => new[] { elt.a, elt.b });

    foreach (var elt in seq) yield return elt;
}
静态IEnumerable生成(字符串s)
{
收益率返回新的正则表达式(“e”)。替换为“,”,1);
收益率回报新正则表达式(“aaaa”)。替换(s,“e”,1);
收益率回报新的正则表达式(“aa”)。替换(s,“bb”,1);
收益率回报新的正则表达式(“ba”)。替换“缩写”,1);
收益率回报新的正则表达式(“bb”)。替换(s,“aa”,1);
var-seq=
生成(新正则表达式(“e”)。替换(s,“,1))
.Zip(generate(new Regex(“aaaa”).Replace(s,“e”,1)),(a,b)=>new{a=a,b=b})。SelectMany(elt=>new[]{elt.a,elt.b})
.Zip(generate(new Regex(“aa”).Replace(s,“bb”,1)),(a,b)=>new{a=a,b=b})。SelectMany(elt=>new[]{elt.a,elt.b})
.Zip(generate(new Regex(“ba”).Replace(s,“abbb”,1)),(a,b)=>new{a=a,b=b}.SelectMany(elt=>new[]{elt.a,elt.b})
.Zip(generate(new Regex(“bb”).Replace(s,“aa”,1)),(a,b)=>new{a=a,b=b});
foreach(var elt,见下文)收益率收益率elt;
}

Eric Lippert在上面提到的帖子中包含了一个
ZipMany
函数。以下是使用
ZipMany
生成
的一个版本:

static IEnumerable<string> generate(string s)
{
    yield return new Regex("e").Replace(s, "", 1);

    yield return new Regex("aaaa").Replace(s, "e", 1);
    yield return new Regex("aa").Replace(s, "bb", 1);
    yield return new Regex("ba").Replace(s, "abbb", 1);

    yield return new Regex("bb").Replace(s, "aa", 1);

    var seq =
        ZipMany(new[]
            {
                generate(new Regex("e").Replace(s, "", 1)),
                generate(new Regex("aaaa").Replace(s, "e", 1)),
                generate(new Regex("aa").Replace(s, "bb", 1)),
                generate(new Regex("ba").Replace(s, "abbb", 1)),
                generate(new Regex("bb").Replace(s, "aa", 1))
            },
            elts => elts).SelectMany(items => items);

    foreach (var elt in seq) yield return elt;
}
静态IEnumerable生成(字符串s)
{
收益率返回新的正则表达式(“e”)。替换为“,”,1);
收益率回报新正则表达式(“aaaa”)。替换(s,“e”,1);
收益率回报新的正则表达式(“aa”)。替换(s,“bb”,1);
收益率回报新的正则表达式(“ba”)。替换“缩写”,1);
收益率回报新的正则表达式(“bb”)。替换(s,“aa”,1);
var-seq=
ZipMany(新[]
{
生成(新正则表达式(“e”)。替换(s,“,1”),
生成(新正则表达式(“aaaa”)。替换(s,“e”,1)),
生成(新正则表达式(“aa”)。替换(s,“bb”,1)),
生成(新正则表达式(“ba”)。替换(s,“abbb”,1)),
生成(新正则表达式(“bb”)。替换(s,“aa”,1))
},
elts=>elts)。选择多个(项目=>items);
foreach(var elt,见下文)收益率收益率elt;
}

您可以使用
Zip
,因为您假设
en*
序列具有相同的长度hey@Rob。我知道您可以压缩两个IEnumerables:
generate(…).zip(generate(…),selector
。但是不清楚指定什么作为
selector
。选择器为序列中的每一对创建一个新对象,因此您可能会有类似
a.zip(b,(左,右)=>new{a=left,b=right}
它将
[1,2,3]
[4,5,6]
转换为
[{a=1,b=4},{a=2,b=5},{a=3,b=6}]
是的-那就好了。在上面的示例中,您可以循环通过zip:
foreach(zip中的var对){yield return pair pair.a;yield return pair pair.b;}
澄清一下:有时使用枚举器是不可避免的;有时确实需要对序列的枚举方式进行细粒度控制。但我的首选是构建一个使用枚举器的更高级别的序列操作,如
ZipMany
,然后将更高级别的操作应用于您的问题。请尝试保持mechanism代码和业务代码是分开的。
SelectMany()
将按不正确的顺序对
>2
序列进行展平。它将生成
[a1,b1,c1,a2,b2,c2]
,而不是
[a1,c1,b1,c2]
。此外,一旦其中一个序列完成,zip将结束。这里,c将首先完成(因为它的发射速度是原来的两倍)并且你会丢失
a
b
中的项目。序列越多,效果越差。@对于这个特定的应用程序,元素的顺序无关紧要。而且,每个子序列都是无限的,因此没有一个子序列会在另一个子序列之前完成。
static IEnumerable<string> generate(string s)
{
    yield return new Regex("e").Replace(s, "", 1);

    yield return new Regex("aaaa").Replace(s, "e", 1);
    yield return new Regex("aa").Replace(s, "bb", 1);
    yield return new Regex("ba").Replace(s, "abbb", 1);

    yield return new Regex("bb").Replace(s, "aa", 1);

    var seq =
        ZipMany(new[]
            {
                generate(new Regex("e").Replace(s, "", 1)),
                generate(new Regex("aaaa").Replace(s, "e", 1)),
                generate(new Regex("aa").Replace(s, "bb", 1)),
                generate(new Regex("ba").Replace(s, "abbb", 1)),
                generate(new Regex("bb").Replace(s, "aa", 1))
            },
            elts => elts).SelectMany(items => items);

    foreach (var elt in seq) yield return elt;
}