以下是项目欧拉挑战(问题2)的解决方案之一。这已经在我的HD上的一个文件夹中存放了几个月,我今天尝试编译/运行它。当我这样做时,我注意到每个值只有4613732
的输出(0
除外,它返回0
)。我不确定这里发生了什么,如果内存正确地为我服务,那么在我写完时工作。任何人都可以指出这个缺陷吗?谢谢。
#include <iostream>
/*
* Problem:
* Each new term in the Fibonacci sequence is generated by adding the
* previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not exceed
four million, find the sum of the even-valued terms.
*/
long int Fib(long int n) //This is a separate function, called Fib(). It is called in the main function below.
{
if (n < 2)
{
return 1;
}
else
{
return Fib(n-1) + Fib(n-2);
}
}
int main()
{
long int sum = 0;
long int upper;
std::cout << "Enter an upper bound for the Fibonacci sequence: ";
/* The Fibonacci sequence will hit 4,000,000 between 35 and 40
* iterations.
*/
std::cin >> upper;
std::cout << std::endl;
for (int i = 1; i < upper; i++)
{
for (Fib(1); Fib(i) < 4000000; i++)
{
if ((Fib(i) % 2) == 0 )
{
sum = sum + Fib(i);
}
}
}
std::cout << std::endl;
std::cout << sum << std::endl; //This is the correct sum for the problem.
return 0;
}
答案 0 :(得分:2)
您在两个for循环中使用相同的变量,并在两者中递增它。一个简单的解决方案是修改你的第一个for循环,然后删除第二个:
for (int i = 1; i < upper && fib(i) < 4000000; i++)
{
if ((Fib(i) % 2) == 0)
{
sum = sum + Fib(i);
}
}
作为旁注:你的方法非常低效,因为你计算每个循环一到三次的fib(i)。减少计算时间的第一种方法非常简单:
for (int i = 1; i < upper && fib(i) < 4000000; i++)
{
int tempFib = Fib(i);
if (tempFib % 2) == 0)
{
sum = sum + tempFib;
}
}
这个新代码在循环中首次计算时保存了fib,这意味着它只被调用两次。你可以移动fib(i)&lt; for循环行之外的4000000语句并进入其自己的行以将其减少为每个循环一个Fibonacci调用。然而,这仍然不是最佳的,因为你仍然每循环调用一次。
在稍微检查一下你的代码之后,我不明白为什么你有一个上界的提示。你已经有了fib(i)&lt;的边界。 4000000。
我的提示是有一个循环计算Fibbonaci数,同时计算总和。这种方法将导致一次Fibbonci计算,而不是大约三十五次。
Fibonacci的迭代方法:
//Calculates the nth Fibonacci number (excluding the first one)
int prev = 1;
int cur = 2;
for( int i = 2; i <= n; ++i){
int temp = prev + cur;
prev = cur;
cur = temp;
}
return cur;
答案 1 :(得分:1)
您在两个i
循环中递增for
。我没看到第二个for
循环是什么。我会这样做:
for (int i = 1; i < upper; i++)
{
if (Fib(i) >= 4000000)
{
break;
}
if ((Fib(i) % 2) == 0 )
{
sum = sum + Fib(i);
}
}
答案 2 :(得分:0)
即使在解决其他帖子提到的双循环问题之后,upper
似乎只是一种快速的纾困方式,在达到400万大关之前。当输入为32时达到四百万个标记,所有32以上的数字将只显示最终结果:4613732
我完全不知道你的代码是如何得到正确的结果的。