2016-11-18 45 views
2

我想写产生的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,... 

这不是幸运数字。

为什么我的代码不工作?通过他们

IEnumerable<int> luckyNumbers = Enumerable.Range(1, int.MaxValue); 
int counter = 1; 
  • 迭代并返回下一个幸运数字:我想:

    1. 开始与所有的自然数

      while (true) 
      { 
          int number = luckyNumbers.ElementAt(counter++); 
          yield return number; 
      
    2. 删除所有n个数字来自序列:

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

    我不明白为什么这不起作用,因为我打算。

  • +2

    请记住,每次执行第3步时,都会以新的顺序结束。现在,你确定你想要新的序列中的“计数器”元素吗?尝试通过一张纸... –

    +0

    @JonSkeet我非常确定,我以为我的意思是每次都要采用上一代序列的下一个元素。但我可以在纸上试一试。 – theonlygusti

    +2

    鉴于维基百科有一个工作的例子,我建议你在调试时遵循这一点。我注意到的第一个问题是,你从第二个元素开始,因为你有'counter = 1'而不是'counter = 0'。这意味着你永远不会返回1,这意味着一个幸运数字。 –

    回答

    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-expression不可编制索引,因此这将始终开始检查每个数字的几个条件。好消息是,你可以简单地使用它作为LuckyNumbers().Take(n)获得第一个n幸运数字。

    +0

    “我认为你初始化为1以避免取消序列中的第1个数字” - 这是真的。 – theonlygusti