-3

我正在尝试解决Project Euler 上的问题 2。问题是:

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

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

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

我正在尝试用 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++ 代码。提前致谢!

4

4 回答 4

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 个元素。我会说“像上面那样”,但你应该以你理解的方式去做。

于 2012-11-27T03:48:20.547 回答
2

让我们一步一步分析你的代码,看看你哪里出错了:

    //ANSWER = 4613732
    int max = 4000000;
    int n;
    int sum;

    for(n=0; n<=max;)
    {

让我们停在这里......这个循环做什么?它从 0 开始循环,直到 n 等于 4000001。问题描述要求您对不超过 4000000 的偶数斐波那契项求和。因此,本质上,您将n其视为存储斐波那契数的变量。好的...

        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循环。会发生什么?

我会给你答案;它可能有点太复杂了,但是如果您花时间在纸上逐步完成它像计算机一样工作,逐行执行每一步,您将看到它是如何工作的,并更好地理解 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;
}

我希望它可以帮助 思考问题并提出自己的解决方案

于 2012-11-27T03:05:22.423 回答
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;

}

于 2013-08-18T15:37:47.487 回答
-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";

繁荣

于 2013-07-18T05:59:02.557 回答