Проект Эйлера - Номер 2 - C # - PullRequest
3 голосов
/ 03 ноября 2011

Я довольно новичок в программировании на C # и подумал, что попытка проблем Эйлера была бы хорошей идеей в качестве стартовой основы. Однако я дошел до того, что не могу получить правильный ответ для Задачи 2.

"Каждый новый термин в последовательности Фибоначчи генерируется путем добавления двух предыдущих терминов. Начиная с 1 и 2, первые 10 членов будут:

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

Рассматривая члены в последовательности Фибоначчи, значения которых не превышают четырех миллионов, найдите сумму четных членов. "

Мой код такой:

int i = 1;
int j = 2;
int sum = 0;

while (i < 4000000) 
{
     if (i < j)
     {
         i += j;

         if (i % 2 == 0)
         {
             sum += i;
         }

     }

     else
     {
         j += i;

         if (j % 2 == 0)
         {
             sum += j;
         }
     }
}

MessageBox.Show("The answer is " + sum);

По сути, я думаю, что я получаю только последние два четных числа последовательности и добавляю их - но я не знаю, как получить все четные числа последовательности и добавить их. Может ли кто-нибудь помочь мне, пытаясь продвинуться с моей начальной точки?

P.S. - Если есть какие-то действительно плохие варианты компоновки, скажем, что устранение их сейчас поможет мне стать лучшим программистом в будущем:)

Заранее большое спасибо.

Ответы [ 8 ]

2 голосов
/ 03 ноября 2011

Я только что вошел в свою учетную запись Project Euler, чтобы увидеть правильный ответ. Как говорят другие, вы забыли добавить начальный член 2, , но в остальном ваш код в порядке (правильный ответ - то, что выводит ваш код + 2), так что хорошо сделано!

Хотя это довольно запутанно, я думаю, что было бы намного яснее, если бы вы использовали 3 переменные, что-то вроде:

int first = 1;
int second = 1;
int newTerm = 0;
int sum = 0;

while (newTerm <= 4000000) 
{
    newTerm = first + second;

    if (newTerm % 2 == 0)
    {
         sum += newTerm;
    }

    first = second;
    second = newTerm;
}

MessageBox.Show("The answer is " + sum);
2 голосов
/ 03 ноября 2011

Вам необходимо установить начальное значение суммы на 2, поскольку вы не включаете его в сумму с текущим кодом.

Кроме того, хотя это может быть менее эффективным с точки зрения использования памяти, явероятно, написал бы код примерно так, потому что IMO он гораздо более читабелен:

var fibonacci = new List<int>();

fibonacci.Add(1);
fibonacci.Add(2);

var curIndex = 1;

while(fibonacci[curIndex] + fibonacci[curIndex - 1] <= 4000000) {
    fibonacci.Add(fibonacci[curIndex] + fibonacci[curIndex - 1]);
    curIndex++;
}

var sum = fibonacci.Where(x => x % 2 == 0).Sum();
2 голосов
/ 03 ноября 2011

Используйте массив fib для хранения последовательности. Его проще кодировать и отлаживать. На каждой итерации вам просто нужно проверить, является ли значение четным.

fib[i] = fib[i - 1] + fib[i - 2];
if (fib[i] > 4000000) break;
if (fib[i] % 2 == 0) sum += fib[i];
0 голосов
/ 19 декабря 2017

Вот моя реализация:

public static int evenFibonachi(int n)
        {
            int EvenSum = 2, firstElem = 1, SecondElem = 2, SumElem=0;

            while (SumElem <= n)
            {
                swich(ref firstElem, ref SecondElem, ref SumElem);
                if (SumElem % 2 == 0)
                    EvenSum += SumElem;
            }

            return EvenSum;
        }

        private static void swich(ref int firstElem, ref int secondElem, ref int SumElem)
        {
            int temp = firstElem;
            firstElem = secondElem;
            secondElem += temp;
            SumElem = firstElem + secondElem;
        }
0 голосов
/ 27 января 2013

Привет, я решил этот вопрос, проверьте, если это правильно. Мой код

          #include<iostream.h>
          #include<conio.h>
          class euler2
            {
              unsigned long long int a;
             public:
            void evensum();
            };
         void euler2::evensum()
          {
             a=4000000;
             unsigned  long long int i;
             unsigned long long int u;

             unsigned long long int initial=0;
             unsigned long long  int initial1=1;
             unsigned long long int sum=0;
          for(i=1;i<=a;i++)
             {
                  u=initial+initial1;
                  initial=initial1;
                  initial1=u;
                if(u%2==0)
                   {

                 sum=sum+u;
                    }
               }
           cout<<"sum of even fibonacci numbers upto 400000 is"<<sum;
         }

             void main()
                 {
                    euler2 a;
                    clrscr();
                    a.evensum();
                    getch();
                  }
0 голосов
/ 09 февраля 2012

Я использовал класс для представления числа Фибоначчи, которое, я думаю, делает код более читабельным.

public class FibonacciNumber
{
    private readonly int first;
    private readonly int second;

    public FibonacciNumber()
    {
        this.first = 0;
        this.second = 1;
    }

    private FibonacciNumber(int first, int second)
    {
        this.first = first;
        this.second = second;
    }

    public int Number
    {
        get { return first + second; }
    }

    public FibonacciNumber Next
    {
        get
        {
            return new FibonacciNumber(this.second, this.Number);
        }
    }

    public bool IsMultipleOf2
    {
        get { return (this.Number % 2 == 0); }
    }
}

Возможно, это слишком далеко, но конечным результатом является функция, которая очень хорошо читается ИМХО:

var current = new FibonacciNumber();
var result = 0;
while (current.Number <= max)
{
    if (current.IsMultipleOf2)
        result += current.Number;

    current = current.Next;
}
return result;

Однако он не будет таким же эффективным, как другие решения, которые не обновляют классы в цикле while. Я полагаю, это зависит от ваших требований, я просто хотел решить проблему и перейти к следующей.

0 голосов
/ 03 ноября 2011

Ваш код немного уродлив, поскольку вы чередуетесь между i и j. Существует гораздо более простой способ вычислить числа Фибоначчи, используя три переменные и постоянно сохраняя их значение.

Одна связанная ошибка заключается в том, что вы проверяете конечное условие только на каждой второй итерации и не в том месте. Но вам повезло, что отсечка соответствует вашей ошибке (число, которое превысило лимит, было странным), так что это не ваша проблема.

Другая ошибка заключается в том, что вы проверяете < вместо <=, но, поскольку число Фибоначчи не равно отсечению, это не вызывает вашей проблемы.

Это также не переполнение int.

Остается только то, что вы забыли взглянуть на первые два элемента последовательности. Только один из них четный, поэтому вам нужно добавить 2 к вашему результату.

int sum = 0; => int sum = 2;

Лично я написал бы одну функцию, которая возвращает бесконечную последовательность Фибоначчи, а затем отфильтровал и суммировал с Linq. Fibonacci().TakeWhile(i=> i<=4000000).Where(i=>i%2==0).Sum()

0 голосов
/ 03 ноября 2011

Я решил это несколько лет назад, поэтому я не помню, как именно это сделал, но у меня есть доступ к форумам, где я об этом говорю. Несколько советов и прямое решение. Числа повторяются в шаблоне. два шанса с последующим четным Таким образом, вы можете пропустить числа без необходимости выполнять операцию модуля.

Предлагаемое решение C # -

        long sum = 0, i0, i1 = 1, i2 = 2;
        do
        {
            sum += i2;
            for (int i = 0; i < 3; i++)
            {
                i0 = i1;
                i1 = i2;
                i2 = i1 + i0;
            }
        } while (i2 < 4000000);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...