我正在尝试解决Project Euler上的Problem 2问题。问题是:
“Fibonacci序列中的每个新术语都是通过添加前两个术语生成的。从1和2开始,前10个术语将是:
1,2,3,5,8,13,21,34,55,89,......
通过考虑Fibonacci序列中的值不超过四百万的项,找到偶数项的总和。“
我试图用C ++解决这个问题。
到目前为止,这是我的代码
#include <iostream>
using namespace std;
int main()
{
//ANSWER = 4613732
int max = 4000000;
int n;
int sum;
for(n=0; n<=max;)
{
while(n%2 == 0)
{
n = (n-1)+(n-2);
}
}
sum = n+=0;
cout << sum << endl;
return 0;
}
正如您所看到的,我知道从搜索它来检查我的答案的正确答案。这段代码我刚刚运行,从未显示答案。任何人都可以给我提示如何达到这个答案,并帮助改进我的C ++代码。提前谢谢!
答案 0 :(得分:5)
这是一种你不应该遵循的方法。 (注意:这篇文章是一个笑话,但我很认真不遵循这种方法。尝试在你的C ++理解水平上理解这种方法也是不明智的。)
#include <iostream>
struct Fib
{
template<int n, int first=1, int second=1> struct Eval { enum {value = Eval<n-1, first, second>::value + Eval<n-2, first, second>::value}; };
template<int first, int second> struct Eval<1, first, second> { enum {value = second}; };
template<int first, int second> struct Eval<0, first, second> { enum {value = first}; };
};
struct SpecificFib
{
template<int n> struct Eval { enum{ value = Fib::template Eval<n, 1, 2>::value }; };
};
template<int... values> struct Sequence {};
template<typename Seq, int n> struct Append;
template<int... values, int n> struct Append<Sequence<values...>, n> { typedef Sequence<values...,n> type; };
template<typename Seq, int n> struct Prepend;
template<int... values, int n> struct Prepend<Sequence<values...>, n> { typedef Sequence<n, values...> type; };
template<typename Func,typename Seq,typename Test=void> struct Filter;
template<typename Func,int first, int... values>
struct Filter<Func,Sequence<first,values...>,typename std::enable_if< Func::template Eval<first>::value>::type>
{
typedef typename Prepend<typename Filter<Func,Sequence<values...>>::type,first>::type type;
};
template<typename Func,int first, int... values>
struct Filter<Func,Sequence<first,values...>,typename std::enable_if< !Func::template Eval<first>::value>::type>
{
typedef typename Filter<Func,Sequence<values...>>::type type;
};
template<typename Func> struct Filter<Func,Sequence<>> { typedef Sequence<> type; };
struct IsEven {
template<int n> struct Eval { enum{ value = !(n%2) }; };
};
template<typename Func,typename Seq> struct Map;
template<typename Func,int first, int... values>
struct Map<Func, Sequence<first,values...>>
{
typedef Sequence<values...> Tail;
typedef typename Map<Func,Tail>::type TailMapped;
enum { firstMapped = Func::template Eval<first>::value };
typedef typename Prepend<TailMapped,firstMapped>::type type;
};
template<typename Func>
struct Map<Func,Sequence<>>
{
typedef Sequence<> type;
};
template<int begin, int end>
struct generate_sequence
{
template<int current, int... values>
struct helper: helper<current-1, current-1, values...> {};
template<int... values>
struct helper<begin, values...>
{
typedef Sequence<values...> type;
};
typedef typename helper<end>::type type;
};
template<typename Seq> struct Sum;
template<int first, int... values> struct Sum<Sequence<first, values...>> { enum {value = first + Sum<Sequence<values...>>::value}; };
template<> struct Sum<Sequence<>> { enum {value = 0}; };
template<typename Seq1, typename Seq2=Sequence<>>
struct Reverse { typedef Seq2 type; };
template<int first, int... values, typename Seq2>
struct Reverse<Sequence<first,values...>, Seq2>:Reverse<Sequence<values...>, typename Prepend<Seq2,first>::type> {};
template<typename Seq, char sep=','> struct PrintHelper;
template<int first, int second, int... values, char sep> struct PrintHelper<Sequence<first,second,values...>, sep>:PrintHelper<Sequence<second,values...>, sep>
{
PrintHelper() { std::cout << sep << first; }
};
template<int last, char sep> struct PrintHelper<Sequence<last>, sep>:PrintHelper<Sequence<>, sep>
{
PrintHelper() { std::cout << last; }
};
template<char sep> struct PrintHelper<Sequence<>,sep> { PrintHelper() {} void Do() const {} };
template<typename Seq, char sep=','> struct Print: PrintHelper< typename Reverse<Seq>::type, sep >
{};
typedef typename generate_sequence<0, 10>::type ZeroTo9;
typedef typename Map<SpecificFib,ZeroTo9>::type First10Fibs;
typedef typename Filter<IsEven,First10Fibs>::type First10FibsThatAreEven;
template<typename Sequence>
void PrintSomeInfo( std::string const& name )
{
std::cout << name << " {";
Print<Sequence>();
std::cout << "} sums to " << Sum<Sequence>::value << "\n";
}
int main()
{
PrintSomeInfo<ZeroTo9>("Zero to 9");
PrintSomeInfo<First10Fibs>("First 10 fibs");
PrintSomeInfo<First10FibsThatAreEven>("First 10 fibs that are even");
}
我希望有所帮助。
上面我正在做的是模板编程。我正在使用相当过于强大的C ++类型系统来推断答案,这样如果编译器正确编译Sum<Sequence>::value
,它将是一个编译时值。
从技术上讲,这是用C ++编写的问题的答案。作为奖励,它将有O(1)
运行时间。 :)
...
更严重。您需要一次一步地解决问题。
编写一个程序,输出序列的前10个元素。我会说“像上面那样”,但你应该以你理解的方式来做。
答案 1 :(得分:2)
让我们一步一步地分析您的代码,看看你出错的地方:
//ANSWER = 4613732
int max = 4000000;
int n;
int sum;
for(n=0; n<=max;)
{
让我们停在这里......这个循环做了什么?它从0开始循环,直到n等于4000001.问题描述要求你对不超过4000000的偶数Fibonacci项求和。所以你基本上将n
视为存储Fibonacci数的变量。 OK ......
while(n%2 == 0)
{
现在这段代码做了什么?它循环,而n
是偶数。你为什么想这么做?
n = (n-1)+(n-2);
行。那么这算什么呢?它有点像,有点像计算斐波纳契数。但是呢?让我们检查!您从n = 0
开始。请注意0 % 2 == 0
所以你要执行这个代码,将n设置为:(0 - 1)+(0 - 2)= 0 - 1 + 0 - 2 = -3。然后循环将退出,因为-3不是偶数。
但是......等等,-3不是斐波那契数字!
记住,斐波那契数,我们称之为F(n),用下面的公式定义:F(n)= F(n - 1)+ F(n - 2),特殊情况为F(0 )= 0和F(1)= 1.换句话说,斐波那契数是前两个斐波那契数的总和。
现在,您所写的表达式是否计算了斐波纳契数?
顺便说一下,此时你应该能够看到为什么这段代码只是运行并运行并运行...如果没有,请记住n
是什么并检查for
循环。会发生什么?
我要给你答案;它可能有点过于复杂,但是如果你花时间逐步完成它 ON PAPER 并按照计算机的方式工作,按照每一步逐行,您将看到它是如何工作的并获得一个更好地理解C和C ++以及如何将算法和数学概念转换为代码。
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
// We store the last 2 Fibonacci numbers that we calculated in this
// small array to improve the performance of our routine and avoid
// having to recalculate things all the time. We update it as we go
// and initialize it with the values for fib(0) and fib(1)
int max = 4000000, ans = 4613732, sum = 0, lfi = 0, lfn = 1;
int lastfibs[2] = { 0, 1 };
do
{
// Calculate the next fibonacci number in the sequence
lfn = lastfibs[0] + lastfibs[1];
// And store it in our cache, updating the cache index
lastfibs[lfi++] = lfn;
if(lfi == 2) // "round and round you're turning me..."
lfi = 0;
if((lfn & 1) == 0) // An even Fibonacci number! Add it to the sum
sum += lfn;
} while(lfn <= max);
if(sum != ans)
cout << "BOO! The sum is " << sum << " but it's supposed to be " << ans << "!" << endl;
else
cout << "Yay! The sum is " << sum << "! Thanks StackOverflow!" << endl;
return 0;
}
我希望它能帮助你 思考解决问题,并提出自己的解决方案。
答案 2 :(得分:0)
bool Ctest::fibonacci(int *fibo, int length)
{
int m = 2, n =1,d,q;
int flag;
if(fibo[0]==0 && fibo[1]==1 && fibo[3]==1)
flag = 1;
for(int i =3; i<length; i++)
{
if(fibo[i] == m)
{
flag = 1;
}
else
{
flag = 0;
}
d = m;
q = m+n;
m=q;
n=d;
}
if (flag == 0)
{
return TRUE;
}
else
return FALSE;
}
答案 3 :(得分:-2)
x = 1;
y = 1;
sum = 0;
a = 0;
while ( x < 4000 ) {
if ( (x % 2) == 0 ){
a = x + a;
}
print "x\n";
sum = x + y;
x = y;
y = sum;
}
print "\na\n";
动臂