Я нашел удивительный трюк, чтобы найти факториалы всего лишь за половину действительного умножения.
Пожалуйста, проявите терпение, так как это довольно длинный пост.
Для четных чисел:
чтобы уменьшить умножение на четные числа вдвое, вы получите 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
Все просто :)
Теперь для нечетных чисел: если число нечетное, сложение такое же, как если бы вы каждый раз вычитали два, но вы останавливаетесь на трех. Однако количество факторов меняется. Если разделить число на два, получится число, оканчивающееся на 0,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это логическая переменная, объявленная статической; он используется для первого случая, когда мы не хотим изменять предыдущую сумму.
Попробуйте как с четными, так и с нечетными числами.