Есть ли метод, который вычисляет факториал в Java?

Я его еще не нашел. Я что-то пропустил? Я знаю, что факторный метод - это обычная программа для начинающих. Но разве было бы полезно иметь стандартную реализацию для повторного использования этого? Я мог бы использовать такой метод со стандартными типами (int, long...) и с BigInteger/BigDecimal.

Ответ 1

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

Ответ 3

public class UsefulMethods {
    public static long factorial(int number) {
        long result = 1;

        for (int factor = 2; factor <= number; factor++) {
            result *= factor;
        }

        return result;
    }
}

Версия Big Numbers от HoldOffHunger:

public static BigInteger factorial(BigInteger number) {
    BigInteger result = BigInteger.valueOf(1);

    for (long factor = 2; factor <= number.longValue(); factor++) {
        result = result.multiply(BigInteger.valueOf(factor));
    }

    return result;
}

Ответ 4

На практике редко нужны голые факториалы. Чаще всего вам понадобится одно из следующих действий:

1) делить один факторный на другой, или

2) приближенный ответ с плавающей запятой.

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

В случае (1), скажем, если x = 90!/85!, тогда вы вычислите результат так же, как x = 86 * 87 * 88 * 89 * 90, без необходимости удерживать 90! в памяти:)

В случае (2), google для "приближения Стирлинга".

Ответ 5

Используйте Guava BigIntegerMath следующим образом:

BigInteger factorial = BigIntegerMath.factorial(n);

(Аналогичная функциональность для int и long доступна в IntMath и LongMath соответственно.)

Ответ 7

Короткий ответ: используйте рекурсию.

Вы можете создать один метод и вызвать этот метод прямо внутри одного и того же метода рекурсивно:

public class factorial {

    public static void main(String[] args) {
        System.out.println(calc(10));
    }

    public static long calc(long n) {
        if (n <= 1)
            return 1;
        else
            return n * calc(n - 1);
    }
}

Ответ 8

Я считаю, что это было бы самым быстрым способом по таблице поиска:

private static final long[] FACTORIAL_TABLE = initFactorialTable();
private static long[] initFactorialTable() {
    final long[] factorialTable = new long[21];
    factorialTable[0] = 1;
    for (int i=1; i<factorialTable.length; i++)
        factorialTable[i] = factorialTable[i-1] * i;
    return factorialTable;
}
/**
 * Actually, even for {@code long}, it works only until 20 inclusively.
 */
public static long factorial(final int n) {
    if ((n < 0) || (n > 20))
        throw new OutOfRangeException("n", 0, 20);
    return FACTORIAL_TABLE[n];
}

Для нативного типа long (8 байтов) он может содержать только 20!

20! = 2432902008176640000(10) = 0x 21C3 677C 82B4 0000

Очевидно, что 21! вызовет переполнение.

Следовательно, для собственного типа long допускается, значимо и корректно только максимум 20!.

Ответ 9

Поскольку факториал растет так быстро, переполнение стека не является проблемой, если вы используете рекурсию. Фактически, значение 20! является самой большой, которую можно представить на Java долго. Таким образом, следующий метод будет либо вычислять factorial (n), либо вызывать исключение IllegalArgumentException, если n слишком велико.

public long factorial(int n) {
    if (n > 20) throw new IllegalArgumentException(n + " is out of range");
    return (1 > n) ? 1 : n * factorial(n - 1);
}

Другой (более холодный) способ сделать то же самое - использовать библиотеку потоков Java 8 следующим образом:

public long factorial(int n) {
    if (n > 20) throw new IllegalArgumentException(n + " is out of range");        
    return LongStream.rangeClosed(1, n).reduce(1, (a, b) -> a * b);
}

Подробнее о Факториалы с использованием потоков Java 8

Ответ 10

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

Ответ 11

Попробуйте это

public static BigInteger factorial(int value){
    if(value < 0){
        throw new IllegalArgumentException("Value must be positive");
    }

    BigInteger result = BigInteger.ONE;
    for (int i = 2; i <= value; i++) {
        result = result.multiply(BigInteger.valueOf(i));
    }

    return result;
}

Ответ 12

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

Пожалуйста, будьте терпеливы, поскольку это немного длинный пост.

Для четных чисел: Чтобы удвоить умножение с четными числами, вы получите n/2 фактора. Первым фактором будет число, в котором вы принимаете факториал, тогда будет следующий номер плюс это число минус два. Следующим номером будет предыдущее число плюс добавленное число минус два. Выполняется, когда последний добавленный вами номер был двумя (то есть 2). Это, вероятно, не имеет большого смысла, поэтому позвольте мне привести вам пример.

8! = 8 * (8 + 6 = 14) * (14 + 4 = 18) * (18 + 2 = 20)

8! = 8 * 14 * 18 * 20 which is **40320** 

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

8! = 1 * 2 * 3 * 4 * 5 * 6 * 7 * 
8! = (1 * 8) * (2 * 7) * (3 * 6) * (4 * 5)
8! = 8 * 14 * 18 * 20

Простой, не так ли:)

Теперь для нечетных чисел: Если число нечетное, добавление такое же, как и вы вычитаете два каждый раз, но вы останавливаетесь на три. Однако число факторов меняется. Если вы разделите число на два, вы получите число, заканчивающееся на .5. Причина в том, что если мы умножим концы вместе, мы останемся со средним числом. В принципе, все это можно решить, разрешив для ряда факторов, равных числу, разделенному на два, округленным. Это, вероятно, не имело большого значения ни для умов без математического фона, поэтому позвольте мне привести пример:

9! = 9 * (9 + 7 = 16) * (16 + 5 = 21) * (21 + 3 = 24) * (roundUp(9/2) = 5)

9! = 9 * 16 * 21 * 24 * 5 = **362880**

Примечание. Если вам не нравится этот метод, вы можете просто взять факториал четного числа перед нечетным (в этом случае восемь) и умножить его на нечетное число (т.е. 9!= 8! * 9).

Теперь можно реализовать его в Java:

public static int getFactorial(int num)
{
    int factorial=1;
    int diffrennceFromActualNum=0;
    int previousSum=num;

    if(num==0) //Returning  1 as factorial if number is 0 
        return 1;
    if(num%2==0)//  Checking if Number is odd or even
    { 
        while(num-diffrennceFromActualNum>=2)
        {
            if(!isFirst)
            {
                previousSum=previousSum+(num-diffrennceFromActualNum);  
            }
            isFirst=false;
            factorial*=previousSum;
            diffrennceFromActualNum+=2;
        }
    }
    else // In Odd Case (Number * getFactorial(Number-1))
    {
        factorial=num*getFactorial(num-1);
    }
    return factorial;
}

isFirst - это логическая переменная, объявленная как статическая; он используется для первого случая, когда мы не хотим менять предыдущую сумму.

Попробуйте как с четными, так и с нечетными номерами.

Ответ 13

Вы можете использовать рекурсию.

public static int factorial(int n){    
      if (n == 0)    
        return 1;    
      else    
        return(n * factorial(n-1));    
     }

а затем после создания метода (функции) выше:

System.out.println(factorial(number of your choice));  
    //direct example
    System.out.println(factorial(3));

Ответ 14

Единственное деловое использование факториала, о котором я могу думать, это формулы Erlang B и Erlang C, и не все работают в колл-центре или телефонной компании. Функция полезности для бизнеса, по-видимому, часто диктует, что появляется на языке - посмотрите на все обработки данных, XML и веб-функции на основных языках.

Легко хранить факторный фрагмент или библиотечную функцию для чего-то подобного.

Ответ 15

Очень простой способ вычисления факториалов:

private double FACT(double n) {
    double num = n;
    double total = 1;
    if(num != 0 | num != 1){
        total = num;
    }else if(num == 1 | num == 0){
        total = 1;
    }
    double num2;
    while(num > 1){
        num2 = num - 1;
        total = total * num2;
        num = num - 1;
    }
    return total;
}

Я использовал double, потому что они могут содержать массивные числа, но вы можете использовать любой другой тип типа int, long, float и т.д.

P.S. Это может быть не лучшее решение, но я новичок в кодировании, и мне потребовалось много времени, чтобы найти простой код, который мог бы рассчитать факториалы, поэтому мне пришлось написать метод самостоятельно, но я помещаю его сюда, чтобы он помогал другим людям, как я.

Ответ 16

Вы также можете использовать рекурсивную версию.

static int myFactorial(int i) {
    if(i == 1)
        return;
    else
        System.out.prinln(i * (myFactorial(--i)));
}

Рекурсия обычно менее эффективна из-за необходимости нажимать и вызывать рекурсии, поэтому итерация выполняется быстрее. С другой стороны, в рекурсивных версиях используется меньшее или меньшее количество локальных переменных, что является преимуществом.

Ответ 17

Факториал - это сильно возрастающая дискретная функция. Поэтому я думаю, что использование BigInteger лучше, чем использование int. Я выполнил следующий код для вычисления факториала неотрицательных целых чисел. Я использовал рекурсию вместо использования цикла.

public  BigInteger factorial(BigInteger x){     
    if(x.compareTo(new BigInteger("1"))==0||x.compareTo(new BigInteger("0"))==0)
        return new BigInteger("1");
    else return x.multiply(factorial(x.subtract(new BigInteger("1")))); 
}

Здесь диапазон большого целого числа

-2^Integer.MAX_VALUE (exclusive) to +2^Integer.MAX_VALUE,
where Integer.MAX_VALUE=2^31.

Однако диапазон упомянутого выше факториального метода может быть увеличен до двух раз с использованием неподписанного BigInteger.

Ответ 18

У нас есть одна строка для вычисления:

Long factorialNumber = LongStream.rangeClosed(2, N).reduce(1, Math::multiplyExact);

Ответ 19

Довольно простой метод

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

Ответ 20

    /**
import java liberary class

*/
import java.util.Scanner;

/* class to find factorial of a number
*/

public class factorial
{
public static void main(String[] args)
{

// scanner method for read keayboard values

    Scanner factor= new Scanner(System.in);

    int n;
    double total = 1;
    double sum= 1;

    System.out.println("\nPlease enter an integer: ");
    n = factor.nextInt();

// evaluvate the integer is greater than zero and calculate factorial

if(n==0)

{
    System.out.println(" Factorial of 0 is 1");
}
else if (n>0)
{
    System.out.println("\nThe factorial of " + n + " is " );

    System.out.print(n);

    for(int i=1;i<n;i++)
    {
        do // do while loop for display each integer in the factorial
              {
                System.out.print("*"+(n-i) );
              }

        while ( n == 1);

      total = total * i;

    }

// calculate factorial
sum= total * n;


// display sum of factorial

    System.out.println("\n\nThe "+ n +" Factorial is : "+" "+ sum);
}

// display invalid entry, if enter a value less than zero

else

{
    System.out.println("\nInvalid entry!!");

}System.exit(0);
}
}

Ответ 21

public static int fact(int i){
    if(i==0)
       return 0;
    if(i>1){
       i = i * fact(--i);
    }

   return i;
}

Ответ 22

Нам нужно реализовать итеративно. Если мы будем внедрять рекурсивно, это вызовет StackOverflow, если ввод станет очень большим (т.е. 2 ​​миллиарда). И нам нужно использовать unbound size number, такие как BigInteger, чтобы избежать арифметического переполнения, когда факторный номер становится больше максимального числа данного типа (т.е. 2 ​​миллиарда для int). Вы можете использовать int для максимум 14 факториалов и долго для максимума 20 факториала до переполнения.

public BigInteger getFactorialIteratively(BigInteger input) {
    if (input.compareTo(BigInteger.ZERO) <= 0) {
        throw new IllegalArgumentException("zero or negatives are not allowed");
    }

    BigInteger result = BigInteger.ONE;
    for (BigInteger i = BigInteger.ONE; i.compareTo(input) <= 0; i = i.add(BigInteger.ONE)) {
        result = result.multiply(i);
    }
    return result;
}

Если вы не можете использовать BigInteger, добавьте проверку ошибок.

public long getFactorialIteratively(long input) {
    if (input <= 0) {
        throw new IllegalArgumentException("zero or negatives are not allowed");
    } else if (input == 1) {
        return 1;
    }

    long prev = 1;
    long result = 0;
    for (long i = 2; i <= input; i++) {
        result = prev * i;
        if (result / prev != i) { // check if result holds the definition of factorial
            // arithmatic overflow, error out
            throw new RuntimeException("value "+i+" is too big to calculate a factorial, prev:"+prev+", current:"+result);
        }
        prev = result;
    }
    return result;
}

Ответ 23

public int factorial(int num) {
        if (num == 1) return 1;
        return num * factorial(num - 1);
}

Ответ 24

while цикл (для небольших чисел)

public class factorial {

public static void main(String[] args) {
    int counter=1, sum=1;

    while (counter<=10) {
        sum=sum*counter;
        counter++;
   }

    System.out.println("Factorial of 10 is " +sum);
   }
}

Ответ 25

Я получил это от EDX, используя его! его названная рекурсия

   public static int factorial(int n) {
    if (n == 1) {
        return 1;
    } else {
        return n * factorial(n-1);
    }
}

Ответ 26

с рекурсией:

public static int factorial(int n)
{
    if(n == 1)
    {
        return 1;
    }               
    return n * factorial(n-1);
}

с циклом while:

public static int factorial1(int n)
{
    int fact=1;
    while(n>=1)
    {
        fact=fact*n;
        n--;
    }
    return fact;
}

Ответ 27

Просто для удовольствия: однострочный факторный метод, который работает с BigInteger:

private static BigInteger calculateFactorial(BigInteger value) 
{
    return value.subtract(BigInteger.ONE).compareTo(BigInteger.ONE) == 0 ? value : value.multiply(calculateFactorial(value.subtract(BigInteger.ONE))); 
}

Ответ 28

ИСПОЛЬЗОВАНИЕ ДИНАМИЧЕСКОГО ПРОГРАММИРОВАНИЯ ЭФФЕКТИВНО

если вы хотите использовать его для расчета снова и снова (например, кеширование)

Java-код:

int fact[]=new int[n+1]; //n is the required number you want to find factorial for.
int factorial(int num)
 {
    if(num==0){
     fact[num]=1;
     return fact[num];
       }
     else
       fact[num]=(num)*factorial(num-1);

     return fact[num];
 }