c# - 为什么这不会产生幸运数字?

标签 c# iteration generator sequences

我正在尝试编写一个生成 lucky numbers 的函数,

static IEnumerable<int> LuckyNumbers()
{
  IEnumerable<int> luckyNumbers = Enumerable.Range(1, int.MaxValue);
  int counter = 1;
  while (true)
  {
    int number = luckyNumbers.ElementAt(counter++);
    yield return number;
    luckyNumbers = luckyNumbers.Where((_, index) => (index + 1) % number != 0);
  }
}

但这会产生:

2,5,7,11,13,17,21,...

这不是幸运数字。

为什么我的代码不起作用?我正在尝试:

  1. 从所有自然数开始:

    IEnumerable<int> luckyNumbers = Enumerable.Range(1, int.MaxValue);
    int counter = 1;
    
  2. 遍历它们并返回下一个幸运数字:

    while (true)
    {
      int number = luckyNumbers.ElementAt(counter++);
      yield return number;
    
  3. 从序列中删除所有第 n 个数字:

    luckyNumbers = luckyNumbers.Where((_, index) => (index + 1) % number != 0);
    

我不明白为什么这不能按我的预期工作。

最佳答案

您的代码不起作用的原因有几个:

  1. 编程中的集合是零索引的。这就是为什么您生成的第一个数字是 2,因为它是索引为 1 的数字。您应该将 counter 初始化为 0。
  2. 我认为您将计数器初始化为 1 以避免取消序列中的第 1 个数字(这将有效地杀死所有数字,因此在给定位置获取元素注定会失败) .问题在于此处幸运数字的定义:虽然第一个幸运数字是 1,但第一次迭代是敲击每个第二 数字。所以你必须采取 Math.Min(number, 2)

最后,您得出以下结果:

    static IEnumerable<int> LuckyNumbers()
    {
        IEnumerable<int> luckyNumbers = Enumerable.Range(1, int.MaxValue);
        int counter = 0;
        while (true)
        {
            int number = luckyNumbers.ElementAt(counter++);
            yield return number;
            int moduloCheck = Math.Max(number, 2);
            luckyNumbers = luckyNumbers.Where((_, index) => (index + 1) % moduloCheck != 0);
        }
    }

不过,从性能的角度来看,我认为该解决方案对于大数来说很糟糕,因为您将永远在 ElementAt 处反复检查第一个数字。因为 where 表达式不可索引,所以这将始终开始检查每个数字的几个 where 条件。好处是您可以简单地将它用作 LuckyNumbers().Take(n) 以获得第一个 n 幸运数字。

关于c# - 为什么这不会产生幸运数字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40671682/

相关文章:

python - 确定Python行开头的实际文件位置

javascript - 如何渲染异步 forEach 'find' 函数数组的结果?

python-3.x - 在生成器中使用上下文管理器是否会导致资源泄漏?

Java,在数组中添加元素并同时循环遍历它

java - 在循环中创建多个 FileWriter 对象

javascript - 我可以将参数传递给 ES6 生成器函数吗

c# - FileSystemWatcher 不适用于从 Windows 服务创建的文件

c# - 如何从 C# 扩展方法中访问 'this'?

c# - 如何告诉 ServiceHost 从任何目录加载程序集

C# 链接到 SharePoint 表单库的编辑表单