C# 为什么';这不会产生幸运数字吗?

C# 为什么';这不会产生幸运数字吗?,c#,iteration,generator,sequences,C#,Iteration,Generator,Sequences,我想写一个函数,生成 这些都不是幸运数字 为什么我的代码不起作用?我正在努力: 从所有自然数开始: IEnumerable<int> luckyNumbers = Enumerable.Range(1, int.MaxValue); int counter = 1; 从序列中删除所有nth编号: luckyNumbers = luckyNumbers.Where((_, index) => (index + 1) % number != 0); 我不明白为什么这不能像我

我想写一个函数,生成

这些都不是幸运数字

为什么我的代码不起作用?我正在努力:

  • 从所有自然数开始:

    IEnumerable<int> luckyNumbers = Enumerable.Range(1, int.MaxValue);
    int counter = 1;
    
  • 从序列中删除所有
    n
    th编号:

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

  • 我不明白为什么这不能像我所希望的那样工作。

    您的代码不能工作有几个原因:

  • 编程中的集合是零索引的。这就是为什么您生成的第一个数字是2,因为它是索引为1的数字。您应该将
    计数器
    初始化为0

  • 我认为您将计数器初始化为
    1
    ,以避免取消序列中的第1个数字(这将有效地杀死所有数字,因此在给定位置获取元素注定失败)。问题在于这里幸运数字的定义:当第一个幸运数字是1时,第一次迭代是每秒钟敲打一次。所以你必须学习
    Math.Min(数字,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);
            }
        }
    
    静态IEnumerable LuckyNumbers()
    {
    IEnumerable-luckyNumbers=Enumerable.Range(1,int.MaxValue);
    int计数器=0;
    while(true)
    {
    int number=luckyNumbers.ElementAt(计数器++);
    收益返回数;
    int moduleCheck=Math.Max(数字,2);
    luckyNumbers=luckyNumbers,其中((uz,index)=>(index+1)%moduleCheck!=0);
    }
    }
    

    但是,从性能的角度来看,我认为解决方案对于大数字来说是可怕的,因为您将在
    元素at
    中反复检查第一个数字。因为where表达式是不可索引的,所以它将始终开始检查每个数字的多个where条件。不过好的是,你可以简单地将它用作
    LuckyNumbers()。取(n)
    来获得第一个
    n
    幸运数字。

    请记住,每次执行步骤3,你都会得到一个新的序列。现在,您确定要从新序列中提取元素
    计数器
    ?试着在一张纸上通读一遍…@JonSkeet我很确定,我想我每次都应该从上一代序列中提取下一个元素。但我可以在纸上试一下。鉴于维基百科有一个有效的例子,我建议您在调试时遵循它。我注意到的第一个问题是,您从第二个元素开始,因为您得到的是
    counter=1
    ,而不是
    counter=0
    。这意味着你永远不会返回1,这是一个幸运数字。算法有点奇怪。对于第一个数字,取
    1
    ,并删除每个
    2
    元素。对于以下所有数字,所采取的数字和朝向下一个已擦除数字的步数等于。因此,我想在进入实际的重现算法表单之前,您必须特别处理
    1
    。“我认为您将计数器初始化为1,以避免取消序列中的第1个数字”——这是正确的。
    while (true)
    {
      int number = luckyNumbers.ElementAt(counter++);
      yield return number;
    
    luckyNumbers = luckyNumbers.Where((_, index) => (index + 1) % number != 0);
    
        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);
            }
        }