提前终止递归迭代器块方法

neo*_*pir 4 c# recursion nunit yield-return

我有一个方法,使用递归函数输出数组的所有排列:

    /// <summary>
    /// Yields a sequence of all permutations in lexical order
    /// </summary>
    /// <typeparam name="T">Type of item in the input sequence</typeparam>
    /// <param name="input">The initial sequence</param>
    /// <returns>A sequence of all permutations in lexical order</returns>
    public IEnumerable<IEnumerable<T>> Permute<T>(IEnumerable<T> input) 
    {
        var list = input.ToList();
        list.Sort(); // into lexical order

        if (list.Count > 2)
        {
            foreach (var item in list)
            {
                var itemArray = new[] {item};
                T[] otherItems = list.Except(itemArray).ToArray();
                foreach (var permutation in Permute(otherItems))
                    yield return itemArray.Concat(permutation).ToArray();
            }
        }
        else 
        {
            yield return new[] {list[0], list[1]};
            yield return new[] {list[1], list[0]};
        }
    }
Run Code Online (Sandbox Code Playgroud)

但是,当我在NUnit测试中运行此函数时,它会比我想象的要早得多:

    [Test]
    public void Can_print_all_permutations()
    {
        foreach (var p in Permute("123456789"))
        {
            Console.WriteLine(new string(p.ToArray()));
        }
    }
Run Code Online (Sandbox Code Playgroud)

这是测试打印的最后一行(我用逗号分隔它们以便发布):

349527816,349527861,349528167,349528176,349528617,3

突然终止使我认为控制台的缓冲和刷新是问题的一个组成部分,但应该打印的最后一行是987654321,所以我觉得循环提前终止.

如果我在循环中包含计算,它甚至更早地终止(在24 ...范围内).

我的实现中有什么东西可以解释这种行为吗?我是否在推动堆栈的极限?

Ale*_*kov 5

您使用的最有可能的测试基础设施具有某种"运行测试的最长时间"限制.枚举所有排列确实需要花费大量时间.

  • 将我想要执行的计算移动到控制台应用程序中会产生我期望的结果,评估所有排列.这使得手指强烈地指向测试框架. (2认同)