Задача из проекта Эйлера, Решение № 1 в C


Любые предложения или комментарии? Это мой стиль хорош?

Сначала я боролся с этой проблемой, я обнаружил, что с помощью "+ = " - оператор дал неправильные результаты. Я тоже попробовал , пока петля в первый раз, что было плохо идеей. Но что на самом деле работал, используя статический аккумулятор переменной.

#include <stdio.h>





static unsigned long total;

int main(void)
{


  total = 0;





  for(unsigned int i = 1; i < 334; i++){

     total  = total + (3*i);


  }




  for(unsigned int j = 1; j < 1000; j++){

    if(j%5==0 && j%3!=0){

      total  = total + j;

    }else{

      total = total + 0;

    }


  }



  printf("Project Euler problem 1 solution = ");
  printf("%lu \n", total);


  return 0;
}

Реф: Эйлера 1: кратные 3 и 5



365
0
задан 28 марта 2018 в 06:03 Источник Поделиться
Комментарии
2 ответа

Ваш код очень трудно читать, поскольку есть так много пустого пространства. Даже если мы не удалим их все, Следующий вариант будет намного легче читать:

#include <stdio.h>

static unsigned long total;

int main(void)
{
total = 0;

for(unsigned int i = 1; i < 334; i++){
total = total + (3*i);
}

for(unsigned int j = 1; j < 1000; j++){

if(j%5==0 && j%3!=0){
total = total + j;
}else{
total = total + 0;
}
}

printf("Project Euler problem 1 solution = ");
printf("%lu \n", total);

return 0;
}

Он подходит даже в примере кода без каких-либо полос прокрутки.


Нет необходимости, чтобы сделать total глобальные. Она должна быть локальной переменной.


Ваш первый for цикл использует оптимизацию, ваша вторая нет. Это асимметричный. Использовать тот же трюк для обеих петель.


total = total + 0 не меняет total на всех. Компилятор, скорее всего, бросит эту линию, но лучше не включать его.


Следующие for петли легче понять:

for(unsigned int i = 0; i < 1000; i += 3) {
total += i;
}


Относительно вашего замечания по +=ты случайно использовать total += total + j? Это даст неверные результаты. Иначе я не могу воспроизвести поведение.


Если вы printf а unsigned intвы должны использовать %uне %lu, поскольку последний предназначен для unsigned long int. Ваш компилятор предупредит вас несовпадение спецификаторы если вы включите предупреждения.


Если вы применить эти комментарии выше, вы в конечном итоге с

#include <stdio.h>

int main(void)
{
unsigned int total = 0;

for(unsigned int i = 0; i < 1000; i += 3){
total += i;
}

for(unsigned int i = 0; i < 1000; i += 5){
if(i % 3 != 0){
total += i;
}
}

printf("Project Euler problem 1 solution = %u \n", total);

return 0;
}

2
ответ дан 28 марта 2018 в 06:03 Источник Поделиться


  • Избежать ненужных вертикали. С другой стороны, горизонтальное пространство вокруг операторы, скобки и т. д. Необходимо.

  • Предпочитаю += там, где это возможно.

  • total = total + 0; нет. Удалить его вместе с целой else пункт.

  • В j петля может быть ускорено в 5 раз, увеличивая j пять:

        for (int j = 0; j < 1000; j += 5) {
    if (j % 3 != 0) {
    total += j;
    }
    }

    По той же линии, i цикл можно переписать как

        for (int i = 0; i < 1000; i += 3) {
    total += i;
    }

    Помимо прочего, это позволяет избежать магическое число 334, который должен какое-то объяснение (если вы вынуждены использовать свои формы, сделать его постоянным с осмысленным именем).


  • Что сказал, проблемы ProjectEuler больше о математике, чем по программированию. Проблема 1 не нуждается в каких-либо кодирования.

1
ответ дан 28 марта 2018 в 06:03 Источник Поделиться