【问题标题】:Yield return in recursion doesn't return value even after ".ToList()" call即使在“.ToList()”调用之后,递归中的收益返回也不返回值
【发布时间】:2016-09-27 14:24:57
【问题描述】:

当我调用生成排列时,第二个 GeneratePermutations(list, startCount, permutationCount) 确实返回 6 次 (yield return permutationList;)。但由于某种原因,第一个GetPermutations 中的result 不包含任何内容,即使我确实在结果上调用了.ToList()

这和递归有什么关系吗?

Test.cs

IEnumerable<int[]> actual = _sut.GetPermutations(3).ToList();

Perm.cs

public class Perm
{
    public IEnumerable<int[]> GetPermutations(int permutationCount)
    {
        int[] permutationList = Enumerable.Range(1, permutationCount).ToArray();
        IEnumerable<int[]> result = GeneratePermutations(permutationList, 0, permutationCount - 1).ToList();

        // Doesn't contain any value!
        return result;
    }

    // http://stackoverflow.com/a/756083/4035
    private IEnumerable<int[]> GeneratePermutations(int[] permutationList, int startCount, int permutationCount)
    {
        if (startCount == permutationCount)
        {
            // Does return 6 times here.
            yield return permutationList;
        }
        else
        {
            for (int i = startCount; i <= permutationCount; i++)
            {
                Swap(ref permutationList, startCount, i);
                GeneratePermutations(permutationList, startCount + 1, permutationCount).ToList();
                Swap(ref permutationList, startCount, i);
            }

        }
    }

    // http://stackoverflow.com/a/2094316/4035
    public static void Swap(ref int[] list, int index1, int index2)
    {
        int tmp = list[index1];
        list[index1] = list[index2];
        list[index2] = tmp;
    }
}

【问题讨论】:

  • 独立于您的问题:在GetPermutations() 中对您的数据类型进行排序。你不需要List&lt;int[]&gt;:把铸件扔掉。
  • @QualityCatalyst:我只是按照建议更改了类型,以防万一在源代码和我的代码中。
  • 请注意refSwap方法中是不需要的。
  • @YacoubMassad 是的,它没有设置为 null 或调整大小/重新初始化,因此 ref 可以省略。
  • @YacoubMassad 是的。我删除了ref,它也可以正常工作。

标签: c# recursion permutation yield


【解决方案1】:

您的问题是,您永远不会返回递归调用的结果,并且您始终使用同一个数组。这将是您代码的最快修复(不是最好的,但我相信您会从这里弄清楚):

IEnumerable<int[]> perms = GeneratePermutations(
    new List<int>(permutationList).ToArray(), 
    startCount + 1, permutationCount);

foreach(int[] perm in perms)
    yield return perm;

顺便说一句:你可以使整个类静态和通用

Proof on dotNetFiddle

【讨论】:

  • 是的,确实问题在于我正在处理同一个permutationList 并且每次都创建一个副本解决了这个问题。谢谢
猜你喜欢
  • 2020-10-05
  • 2016-10-04
  • 2021-01-29
  • 1970-01-01
  • 1970-01-01
  • 2012-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多