2016-05-06 4 views
0

Я хочу создать метод, который найдет произведение всех целых чисел от 1 до n включительно. Вот мой код, но на самом деле не делать то, что я хочу:Как написать факториальную функцию?

public class MathUtil{ 

    int result; 

    public int product(int n){ 

     for (int i = 1; i <= n; i++){ 

      result = result * n * i; 

     } 

     return result; 

    } 

} 

ответ

0

... Другими словами, n!

  • result должен быть инициализирован в 1
  • result не должно быть поле, но локальная переменная
  • Не умножать на i * n, только i
  • Для расчета стоимости товаров с 1 по n, это может быть неплохо проверить, что n >= 1

Как это:

public int product(int n) { 
    if (n < 1) { 
     throw new IllegalArgumentException("n must be 1 or greater"); 
    } 

    int result = 1; 
    for (int i = 2; i <= n; i++) { 
     result *= i; 
    } 
    return result; 
} 

Имейте в виду, что это будет быстро переливной для n > 12, или если изменить тип возвращаемого значения long, то для n > 20. (Спасибо @FredK за указание на это!)

+0

Также отметим, что если результатом является int вы будете переполняться для любого n> 12, и если он длинный, вы переполнитесь, если n> 20 – FredK

+0

@FredK хорошая точка, должным образом отмеченная, спасибо! – janos

3

Ну result инициализируется как 0. Затем в цикле, нужно умножить его на что-то и установить результат result. Как мы знаем, все, умноженное на ноль, равно нулю. Рассмотрим инициализацией result, как 1

int result = 1; 

Кроме того, логика умножение неправильно. Почему вы умножаетесь на n и i? Просто умножить result на i

0

Здесь вы идете:

public class MathUtil 
{ 

    public int product(int n) 
    { 
     if (n < 3) return n; // no need to do any stuff if n is less then 3, 
         // since the result will be n... 
     int result = 1; // result must be here 
     for (int i = 2; i <= n; i++) // start from 2 
     { 
      result *= i; // don't need n here 
          // and you can make it shorter with *= 
     } 
     return result; 
    } 
} 

Примечание для result; Допустим, вы вызвали этот метод с n = 3. result будет 6, но он будет установлен таким образом, если его переменная класса, поэтому, когда вы вызываете этот метод с n = 4 после этого для того же экземпляра этого класса, возвращается 146, и с ним будет установлено result. Вот почему вам нужно сделать его методом переменной, поэтому его 1 всякий раз, когда вызывается метод, независимо от того, какой экземпляр этого класса.

Кроме того, если вы делаете это переменной класса и устанавливаете в 1 каждый раз, когда вы вызываете этот метод, он все равно может создавать проблемы с синхронизацией, если два потока вызывают этот метод в одном экземпляре этого класса, поэтому избегайте этого (даже если вы не планируете такую ​​вещь, это хорошая практика).

0

Рекурсия прекрасно работает здесь, тоже ...

public int product(int someNum) { 
    if (someNum == 1) return 1; 
    return someNum * product(someNum-1); 
} 

В тройном формате:

public int product(int someNum) { 
    return (someNum == 1) ? 1 : someNum * product(someNum -1); 
} 
+0

Примечание. Я не проверю, что указанное число больше 1, что приведет к ошибке, если вы сделаете это именно так. –

Смежные вопросы