Факториал с использованием рекурсии в Java
Я изучаю Java, используя книгу Java: The Complete Reference.
В настоящее время я работаю над рекурсией.
Обратите внимание: В stackoverflow есть похожие вопросы. Я искал их, но я не нашел решения по моему вопросу. Я смущен логикой в следующей программе.
Если я запустил программу ниже, она выдаст правильный вывод, но я не понял логику.
class Calculation
{
int fact(int n)
{
int result;
if(n==1)
return 1;
result = fact(n-1) * n;
return result;
}
}
public class Factorial
{
public static void main(String args[])
{
Calculation obj_one = new Calculation();
int a = obj_one.fact(4);
System.out.println("The factorial of the number is : " + a);
}
}
Ответы
Ответ 1
result
является локальной переменной метода fact
. Поэтому каждый раз, когда вызывается метод факта, результат сохраняется в другой переменной, чем предыдущий вызов факта.
Итак, когда факт вызывается с аргументом 3 в качестве аргумента, вы можете себе представить, что его результат
result3 = fact(2) * 3
result3 = result2 * 3
result3 = 1 * 2 * 3
Ответ 2
Сначала вы должны понимать, как работает факториал.
Давайте возьмем 4! в качестве примера.
4! = 4 * 3 * 2 * 1 = 24
Моделируем код, используя приведенный выше пример:
int fact(int n)
{
int result;
if(n==0 || n==1)
return 1;
result = fact(n-1) * n;
return result;
}
В большинстве языков программирования у нас есть то, что мы называем function stack
. Это как колода карт, где каждая карта помещена над другой - и каждая карта может считаться функцией. Итак, передавая метод fact
:
Уровень стека 1: fact(4) // n = 4 and is not equal to 1. So we call fact(n-1)*n
Уровень стека 2: fact(3)
Уровень стека 3: fact(2)
Уровень стека 4: fact(1)
//now, n = 1., поэтому мы возвращаем 1 из этой функции.
возвращаемые значения...
Уровень стека 3: 2 * fact(1) = 2 * 1 = 2
Уровень стека 2: 3 * fact(2) = 3 * 2 = 6
Уровень стека 1: 4 * fact(3) = 4 * 6 = 24
так что мы получили 24.
Обратите внимание на следующие строки:
result = fact(n-1) * n;
return result;
или просто:
return fact(n-1) * n;
Это вызывает функцию. Используя 4 в качестве примера,
В последовательности согласно стекам функций.
return fact(3) * 4;
return fact(2) * 3 * 4
return fact(1) * 2 * 3 * 4
Подстановка результатов...
return 1 * 2 * 3 * 4 = return 24
Надеюсь, вы поняли.
Ответ 3
Вот еще одно объяснение того, как работает факторный расчет с использованием рекурсии.
Немного измените исходный код:
int factorial(int n) {
if (n <= 1)
return 1;
else
return n * factorial(n - 1);
}
Ниже приведено описание 3!:
![введите описание изображения здесь]()
Источник: RECURSION (Java, С++) | Алгоритмы и структуры данных
Ответ 4
Ваше замешательство, я считаю, происходит от того факта, что вы считаете, что существует только одна переменная result
, тогда как на самом деле существует переменная result
для каждого вызова функции. Поэтому старые результаты не заменяются, но возвращаются.
ДЛЯ РАЗРАБОТКИ:
int fact(int n)
{
int result;
if(n==1)
return 1;
result = fact(n-1) * n;
return result;
}
Предположим, что вызов fact(2)
:
int result;
if ( n == 1 ) // false, go to next statement
result = fact(1) * 2; // calls fact(1):
|
|fact(1)
| int result; //different variable
| if ( n == 1 ) // true
| return 1; // this will return 1, i.e. call to fact(1) is 1
result = 1 * 2; // because fact(1) = 1
return 2;
Надеюсь, теперь это станет понятным.
Ответ 5
public class Factorial {
public static void main(String[] args) {
System.out.println(factorial(4));
}
private static long factorial(int i) {
if(i<0) throw new IllegalArgumentException("x must be >= 0");
return i==0||i==1? 1:i*factorial(i-1);
}
}
Ответ 6
Что происходит, так это то, что сам рекурсивный вызов приводит к дальнейшему рекурсивному поведению. Если вы должны были написать это, вы получите:
fact(4)
fact(3) * 4;
(fact(2) * 3) * 4;
((fact(1) * 2) * 3) * 4;
((1 * 2) * 3) * 4;
Ответ 7
Ключевым моментом, который вы здесь не видите, является то, что переменная "result" является переменной стека, и поэтому она не получает "замену". Чтобы уточнить, каждый раз, когда вы вызываете факт, в интерпретаторе внутренне создается интерпретатор NEW, называемый "результат", и связан с этим вызовом методов. Это контрастирует с объектными полями, связанными с экземпляром объекта, а не с конкретным вызовом метода
Ответ 8
Хотя это и старо, все еще продолжает хорошо расти в Google. Поэтому я решил, что упомянул об этом. Никто не упоминается, чтобы проверить, когда x = 0.
0! и 1! оба = 1.
Это не проверяется с помощью предыдущих ответов и вызывает переполнение стека, если был запущен факт (0). Во всяком случае, простое исправление:
public static int fact(int x){
if (x==1 | x==0)
return 1;
return fact(x-1) * x;
}// fact
Ответ 9
Рекурсивное решение с использованием тернарных операторов.
public static int fac(int n) {
return (n < 1) ? 1 : n*fac(n-1);
}
Ответ 10
На мой взгляд, и если вы считаете, что кто-то знает знание java уровня начинающего уровня, я бы предложил, чтобы n == 1 был изменен на n <= 1 или (n == 0) || (n == 1), потому что факториал 0 равен 1.
Ответ 11
Правильный вариант:
int factorial(int n)
{
if(n==0||n==1)
return 1;
else
return n*factorial(n-1);
}
Это вернет 1 для факториала 0. Поверьте мне. Я усвоил этот трудный путь.
Просто для того, чтобы не поддерживать условие для 0, не удалось прояснить собеседование.
Ответ 12
Чтобы понять это, вы должны объявить метод самым простым способом, и мартинас прибил его 6 мая:
int fact(int n) {
if(n==0) return 1;
else return n * fact(n-1);
}
прочитайте приведенную выше реализацию, и вы поймете.
Ответ 13
ИМХО, ключом к пониманию действий, связанных с рекурсией, является:
- Сначала мы рекурсивно погружаемся в стек, и с каждым вызовом мы каким-то образом модифицируем значение (например, n-1 в
func(n-1);
), которое определяет, должна ли рекурсия идти все глубже и глубже. - После выполнения recursionStopCondition (например,
n == 0
) рекурсии прекращаются, и методы выполняют фактическую работу и возвращают значения вызывающему методу в верхних стеках, что приводит к пузырю на вершине стека. - Важно перехватить значение, возвращаемое из более глубокого стека, каким-то образом изменить его (умножив на n в вашем случае), а затем вернуть это измененное значение сверху стека. Распространенной ошибкой является то, что значение из самого глубокого фрейма стека возвращается прямо к вершине стека, поэтому все вызовы методов игнорируются.
Конечно, методы могут выполнять полезную работу до того, как они погрузятся в рекурсию (сверху донизу стека) или на обратном пути.
Ответ 14
Используя Java 8 и выше, используя саму рекурсию
UnaryOperator<Long> fact = num -> num<1 ? 1 : num * this.fact.apply(num-1);
И используйте это как
fact.apply(5); // prints 120
Внутренне это рассчитать как
5*(4*(3*(2*(1*(1)))))
Ответ 15
не создайте еще одну переменную
результат
просто
return fact (n-1) * n;
class Calculation
{
int fact(int n)
{
int result;
if(n==1)
return 1;
return fact(n-1) * n;
}
}
Ответ 16
import java.util.Scanner;
public class Factorial {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
int n;
System.out.println("Enter number: ");
n = keyboard.nextInt();
int number = calculatefactorial(n);
System.out.println("Factorial: " +number);
}
public static int calculatefactorial(int n){
int factorialnumbers=1;
while(n>0){
factorialnumbers=(int)(factorialnumbers*n--);
}
return factorialnumbers;
}
}
Ответ 17
public class Factorial2 {
public static long factorial(long x) {
if (x < 0)
throw new IllegalArgumentException("x must be >= 0");
if (x <= 1)
return 1; // Stop recursing here
else
return x * factorial(x-1); // Recurse by calling ourselves
}
}
Ответ 18
public class Factorial {
public static void main(String[] args) {
int n = 7;
int result = 1;
for (int i = 1; i <= n; i++) {
result = result * i;
}
System.out.println("The factorial of 7 is " + result);
}
}
Ответ 19
Ну вот логика, чтобы найти факториал числа с помощью рекурсии,
static int factorialFunction(int n)
{
int result;
if(n == 1)
{
return 1;
}
// here we are calling the recursion function
result = factorialFunction(n - 1) * n;
return result;
}
Между тем вы можете обратиться к этому ресурсу, чтобы найти примеры факториала числа с помощью рекурсии.