【问题标题】:What is Sum of Even Terms In Fibonacci (<4million)? [Large Value Datatype Confusion]斐波那契偶数项的总和是多少(<400 万)? [大值数据类型混淆]
【发布时间】:2009-10-29 15:14:44
【问题描述】:

从 1 和 2 开始,斐波那契数列的前 10 项将是:

1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

求序列中所有不超过 400 万的偶数项之和。


现在,我知道了如何做到这一点。但我对保存如此大数据的数据类型感到困惑。 int 我得到了奇怪的结果。 :(

更多:它的 Project Euler 第二个问题。但我无法得到它。我得到了疯狂的价值观作为答案。有人可以发布理想的程序吗?

编辑:这是我为将斐波那契打印到屏幕上所写的内容。基本款。即使我给出 100 作为限制,我的变量也会变得疯狂。我的代码错了吗?

// Simple Program to print Fibonacci series in Console
#include <stdio.h>
int main() {
    int x=1,y=2,sum=0,limit=0,i=0,temp=0;
    printf("Enter Limit:");
    scanf("%d",&limit);

    if(limit==1)
        printf("%d",x);
    else if(limit>1) {
        printf("%d %d",x,y);
        if (limit>2) {
            while (i<limit-2) {
                temp=y;
                sum=x+y;
                x=temp;
                y=sum;
                printf(" %d",sum);
                i++;
            }
        }
    }      

    printf("\n");
    return 0;
}

已解决:实际上,我自己设法找到了解决方案。这是我的程序。它有效。

#include <stdio.h>
int main() {
    int x=1,y=2,sum,limit;     //Here value of first 2 terms have been initialized as 1 and 2
    int evensum=2;             //Since in calculation, we omit 2 which is an even number
    printf("Enter Limit: ");   //Enter limit as 4000000 (4million) to get desired result
    scanf("%d",&limit);
    while( (x+y)<limit ) {
        sum=x+y;
        x=y;
        y=sum;
        if (sum%2==0)
            evensum+=sum;
    }
    printf("%d \n",evensum);
    return 0;
}

【问题讨论】:

  • 这看起来更像是 ProjetEuler 问题,而不是我的作业。
  • 实际上,是的,它是一个 Project Euler 问题。但我就是无法让它工作。我的程序给了我 -ve 值和所有结果:(

标签: c types fibonacci


【解决方案1】:

由于您只想要最多 400 万,int 可能不是您的问题。

很可能您的程序有问题并且数据存储很好,因此您应该在较小的值上测试您的程序。例如,很明显,前三个偶数项的总和是 44(提示:每第三个项是偶数),所以如果你以 50 的上限运行程序,那么你应该立即得到 44。继续运行小型测试用例,以获得对大型测试用例的信心。

【讨论】:

    【解决方案2】:

    为安全起见,请使用“长”数据类型; C 标准要求至少保存 40 亿个,但在大多数机器上,'int' 也将保存 40 亿个。

    enum { MAX_VALUE = 4000000 };
    int sum  = 0;
    int f_n0 = 0;
    int f_n1 = 1;
    int f_n2;
    
    while ((f_n2 = f_n0 + f_n1) < MAX_VALUE)
    {
        if (f_n2 % 2 == 0)
            sum += f_n2;
        f_n0 = f_n1;
        f_n1 = f_n2;
    }
    printf("%d\n", sum);
    

    【讨论】:

      【解决方案3】:

      我不是程序员,但这是对 Leffler 代码的改编,没有 IF 标准。根据我在偶数斐波那契数列中发现的模式:0,2,8,34,144,610,2584... 有趣的是:f_n2 = 4 *f_n1 + f_n0。这也意味着这个程序只需要 1/3 的计算,因为它甚至不考虑/计算奇数斐波那契数。

      enum { MAX_VALUE = 4000000 };
      int sum  = 2;
      int f_n0 = 0;
      int f_n1 = 2;
      int f_n2 = 8;
      
      while (f_n2 < MAX_VALUE)
      {
          sum += f_n2;
          f_n0 = f_n1;
          f_n1 = f_n2;
          f_n2 = 4*f_n1 + f_n0;
      }
      printf("%d\n", sum);
      

      【讨论】:

        【解决方案4】:

        尝试改变这个:

        while (i<limit-2)
        

        到这里:

        while (y<limit)
        

        正如所写,您的程序正在循环,直到它到达第 4 百万个斐波那契数(即当 i 到达 400 万时,尽管显然首先发生了溢出)。循环应检查 y(较大的斐波那契数)何时大于 400 万。

        【讨论】:

          【解决方案5】:

          伙计们,我得到了答案。我确认了结果并且 int 可以处理它。这是我的程序:

          #include <stdio.h>
          int main() {
              int x=1,y=2,sum,limit;     //Here value of first 2 terms have been initialized as 1 and 2
              int evensum=2;             //Since in calculation, we omit 2 which is an even number
              printf("Enter Limit: ");   //Enter limit as 4000000 (4million) to get desired result
              scanf("%d",&limit);
              while( (x+y)<limit ) {
                  sum=x+y;
                  x=y;
                  y=sum;
                  if (sum%2==0)
                      evensum+=sum;
              }
              printf("%d \n",evensum);
              return 0;
          }
          

          感谢所有回复和帮助。 “思考我的脚”来救援:)

          【讨论】:

          • 在这里,我认为您正在遍历所有斐波那契数。我认为这不是有效的方法。相反,我们可以直接计算偶数,因为它们出现在每三个位置的倍数处。它可能会降低复杂性。
          【解决方案6】:

          int 足以容纳几乎每个现代系统上的数百万个值,但如果您担心它,可以使用long。如果这仍然给您带来奇怪的结果,那么问题出在您的算法上。

          【讨论】:

          • intlong 的含义取决于编程语言、操作系统和 CPU 架构。在 Linux 上使用 C 的 x86 上,它们都是 32 位的
          • 在 x86_64 with C on Windows 上,它们仍然都是 32 位的。
          【解决方案7】:

          使用BigInt

          再说一次,unsigned int 存储的值超过 40 亿,因此即使“所有斐波那契数的总和不超过 400 万”(显然,它必须小于 8 mil)?

          【讨论】:

          • 我是 C 新手。我不熟悉各种类型的格式说明符。这会是问题吗?
          • 格式说明符如printf()?这可能是a 问题,如果不是the 问题。您使用什么数据类型,以及您使用什么转换说明符进行输出?
          【解决方案8】:

          您的程序打印 F_1 + ..+ F_limit 而不是 F_1 + ... F_n 与 F_n

          查看关于Fibonacci NumbersSloane A000045 的维基百科文章:斐波那契数呈指数增长。检查这个table F_48 = 4807526976,它超过了int。 F_100 是 354224848179261915075 肯定会溢出甚至 int64_t (不过你的堆栈没有)。

          【讨论】:

            【解决方案9】:

            一个有趣的解决方案是对斐波那契数列使用封闭形式,对几何级数使用封闭形式。最终解决方案如下所示:

              sum = ( (1-pow(phi_cb, N+1)) / (1-phi_cb) - (1-pow(onephi_cb,N+1)) / (1-onephi_cb)) / sqrt(5);
            

            在哪里

              double phi       = 0.5 + 0.5 * sqrt(5);
              double phi_cb    = pow(phi, 3.0);
              double onephi_cb = pow(1.0 - phi, 3.0);
              unsigned N = floor( log(4000000.0 * sqrt(5) + 0.5) / log(phi) );
              N = N / 3;
            

            当然还有关于 double 到 int 类型转换的所有注意事项。

            【讨论】:

              【解决方案10】:

              斐波那契数列中的每个新项都是通过添加前两项来生成的。从 1 和 2 开始,前 10 个术语将是:

              1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

              通过考虑斐波那契数列中值不超过四百万的项,求偶数项之和。

                 int main()
              
                {  
                   long first = 1, second = 2, next, c;
              
                   int sum=0;
                   for ( c = 1 ; c <100000000; c++ )
              
                {
              
                   next = first + second;
                   if(next>=4000000)
                   {
                   next=  next-second;
                   break;
                   }
              
                   first = second;
                   second = next;    
              
                if(next%2==0){
              
                   sum=sum+next;
                }
              
               }
              
                printf("the sum of even valued  term is %d\n",sum+2);
              
              
               }  
              

              【讨论】:

                【解决方案11】:

                这是我的程序:

                #include <iostream>
                
                long int even_sum_fibonacci(int n){
                    int i = 8;
                    int previous_i = 2;
                    int next_i = 0;
                    long int sum = previous_i + i;;
                    while(n>next_i){
                        next_i = i*4 + previous_i;
                        previous_i = i;
                        i = next_i;
                        sum = sum + i;
                    }
                    return sum - next_i; //now next_i and i are both the bigger number which
                                         //exceeds 4 million, but we counted next_i into sum
                                         //so we'll need to substract it from sum
                }
                
                
                
                int main()
                {
                   std::cout << even_sum_fibonacci(4000000) << std::endl; 
                
                   return 0;
                }
                

                因为如果您查看斐波那契数列(前几个偶数) 2 8 34 144 610 2584 ... 你会看到它与 next_number = current_number * 4 + previous_number

                这是解决方案之一。所以结果是4613732

                【讨论】:

                  【解决方案12】:

                  你可以试试下面的代码。

                  public static void SumOfEvenFibonacciNumbers()
                  {
                      int range = 4000000;
                      long sum = 0;
                      long current = 1;
                      long prev = 0;
                      long evenValueSum= 0;
                      while (evenValueSum< range)
                      {
                          sum = prev + current;
                          prev = current;
                          current = sum;
                          if (sum % 2 == 0 )
                          {
                              evenValueSum = evenValueSum+ sum;
                          }
                      }
                  
                      Console.WriteLine(evenValueSum);
                  }
                  

                  【讨论】:

                    【解决方案13】:

                    你可以使用上面的代码。

                    import numpy as np
                    M = [[0,1],[1,1]]
                    F = [[0],[1]]
                    s = 0
                    while(F[1][0] < 4000000):
                     F = np.matmul(M, F)
                     if not F[0][0]%2:
                       s+=F[0][0]
                    
                    print(s)
                    

                    我们可以在 O(log n) 时间内做得比这更好。此外,一个 2 × 2 矩阵和一个二维向量可以在 O(1) 时间内再次相乘。因此计算 Mn 就足够了。 以下递归算法计算 Mn

                    1. 如果 n = 0,则返回 I2
                    2. 如果 n = 1,则返回 M。
                    3. 如果 n = 2m。
                    4. 递归计算 N = Mm,并设置 P = N2
                    5. 如果 n = 2m+1,则设置 P = PM。
                    6. 返回 P。 我们有 T(n) = T(n/2) + O(1),根据大师定理 T(n) = O(log n)

                    您还可以对偶数斐波那契数列使用递归: EFn = 4EFn-1 + EFn-2 带有种子值 EF0 = 0 和 EF1 = 2。

                    【讨论】:

                      【解决方案14】:

                      简单的解决方案是:-

                      #include <iostream>
                      using namespace std;
                      
                      int main(int argc, char** argv) {   
                      int n1=1;
                      int n2=2;
                      int num=0,sum;
                      
                      for (int i=1;i,n1<4000000;i++)
                      {
                      
                          cout<<"    "<<n1;
                          num=n1+n2;
                          if(!(n1%2))
                          {
                              sum+=n1;
                          }
                          n1=n2;
                          n2=num;     
                      }
                      cout<<"\n Sum of even term is = "<<sum;
                      return 0;
                      }
                      

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 2021-12-21
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2015-07-25
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多