2011-11-18 11 views
24

Estoy aprendiendo Java usando el libro Java: The Complete Reference. Actualmente estoy trabajando en el tema Recursión.Factorial usando Recursion en Java

Tenga en cuenta: Hay preguntas similares en stackoverflow. Los busqué pero no encontré la solución a mi pregunta. Estoy confundido con la lógica en el siguiente programa.

Si ejecuto el siguiente programa, produce la salida correcta, pero no entendí la lógica.

  • No entendí la lógica en la siguiente línea: resultado = hecho (n-1) * n;
  • De mis conocimientos, Si pasamos el valor de n = 4, como se muestra en el siguiente programa,
  • A continuación, se almacena 3 * 4 en el resultado, es decir, 12.
  • De nuevo, hecho de (n- 1) se llama. Entonces se convierte en n 3.
  • A continuación, el 2 * 3 se almacena en el resultado en sustitución del anterior 12.
  • creo que usted entiende donde estoy atascado hacia arriba/confundido.

  • Gracias.

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

Mi consejo es que antes de profundizar en Java, primero debe entender las matemáticas detrás de la recursión. Si aún no lo has hecho, este será un muy buen comienzo para ti en.wikipedia.org/wiki/Recursion – GETah

+1

Espero que esto te aclare mucho más http://www.programmerinterview.com/index.php/recursion/explanation-of-recursion/ – Rangesh

Respuesta

9

es una variable local del método fact. Por lo tanto, cada vez que se llama al método de hecho, el resultado se almacena en una variable diferente de la invocación de hecho anterior.

Por eso, cuando de hecho se invoca con 3 como argumento, se puede imaginar que su resultado es

result3 = fact(2) * 3 
result3 = result2 * 3 
result3 = 1 * 2 * 3 
8

Su confusión, creo, viene del hecho de que parece que sólo una result variables, mientras que en realidad no es una variable result para cada llamada a la función. Por lo tanto, los resultados antiguos no se reemplazan, sino que se devuelven.

para elaborar:

int fact(int n) 
{ 
    int result; 

    if(n==1) 
    return 1; 

    result = fact(n-1) * n; 
    return result; 
} 

asumir una llamada a 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; 

espero que sea más claro ahora.

+0

Ya, entendiste mi punto. ¿Puedes por favor elaborar? – user907629

2

El punto clave que falta aquí es que la variable "número" es una variable de pila, y como tal no se "reemplaza". Para elaborar, cada vez que se llama a un hecho, se crea una variable NUEVA llamada "resultado" internamente en el intérprete y se vincula a esa invocación de los métodos. Esto es en contraste con los campos de objeto que se vincularon con la instancia del objeto y no con un método específico llamada

46

Primero debe comprender cómo funciona el factorial.

¡Tomemos 4! como ejemplo.

4! = 4 * 3 * 2 * 1 = 24 

Vamos a simular el código usando el ejemplo anterior:

int fact(int n) 
    { 
     int result; 
     if(n==0 || n==1) 
     return 1; 

     result = fact(n-1) * n; 
     return result; 
    } 

En la mayoría de lenguajes de programación, tenemos lo que llamamos function stack. Es igual que una baraja de cartas, donde se coloca cada tarjeta por encima del otro - y cada tarjeta puede ser pensado como una función tanto, la transmisión de método fact:

nivel 1: fact(4) // n = 4 and is not equal to 1. So we call fact(n-1)*n

Pila nivel 2: fact(3)

nivel de pila 3: fact(2)

nivel de pila 4: fact(1) // ahora, n = 1. así volvemos 1 de esta función.

valores que regresan ...

nivel 3: 2 * fact(1) = 2 * 1 = 2

nivel 2: 3 * fact(2) = 3 * 2 = 6

nivel 1: 4 * fact(3) = 4 * 6 = 24

así que conseguimos 24.

Take nota de estas líneas:

result = fact(n-1) * n; 
      return result; 

o simplemente:

return fact(n-1) * n; 

Este llama a la función en sí. Utilizando 4 como ejemplo,

En secuencia de acuerdo con la función pilas ..

return fact(3) * 4; 
return fact(2) * 3 * 4 
return fact(1) * 2 * 3 * 4 

Sustituyendo resultados ...

return 1 * 2 * 3 * 4 = return 24 

espero que usted consigue el punto.

+0

Creo que significaba // n = 4 y no es igual a 1. No estoy seguro de dónde venía el 12. – Gray

+0

sí ... editado ... gracias .. –

+0

Lo que quise decir fue, factorial de 4 = 4 * 3 * 2 * 1. Soy mi pregunta, al principio pensé que el valor 4 * 3 se almacenará en el resultado. – user907629

5

Lo que sucede es que la llamada recursiva en sí misma da como resultado un comportamiento recursivo adicional. Si se va a escribirlo que se obtiene:

fact(4) 
fact(3) * 4; 
(fact(2) * 3) * 4; 
((fact(1) * 2) * 3) * 4; 
((1 * 2) * 3) * 4; 
1

Aunque esto es viejo, todavía sigue saliendo bastante bien en Google. Así que pensé en mencionar esto. Nadie mencionado para comprobar cuando x = 0.

0! ¡y 1! both = 1.

Esto no se está comprobando con las respuestas anteriores, y causaría un desbordamiento de la pila, si se ejecutara el hecho (0).De todos modos solución sencilla:

public static int fact(int x){ 
    if (x==1 | x==0) 
     return 1; 
    return fact(x-1) * x; 
}// fact 
-1

no crean una variable más

resultado

simplemente

retorno hecho de (n-1) * n;

class Calculation 
{ 
    int fact(int n) 
    { 
     int result; 

     if(n==1) 
     return 1; 

     return fact(n-1) * n; 

    } 
} 
-1
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; 
    } 
} 
0

En mi opinión, y que siendo la opinión de alguien con conocimientos de nivel de principiante en java, sugeriría que el n == 1 a cambiarse a < n = 1 o (n == 0) || (n == 1) porque el factorial de 0 es 1.

-1
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 
    } 
} 
1

Una solución recursiva utilizando operadores ternarios.

public static int fac(int n) { 
    return (n < 1) ? 1 : n*fac(n-1); 
} 
+3

return n == 1 || n == 0? 1: n * fac (n - 1); – ggb667

+0

return (n <= 1)? 1: n * hecho (n-1) –

0

la correcta es:

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

Este volverían 1 para factorial 0. No me creen. Lo he aprendido de la manera difícil. Solo por no mantener la condición para 0 no pudo despejar una entrevista.

0

Para entenderlo hay que declarar el método de la forma más sencilla posible y Martynas clavado en mayo de post sexto:

int fact(int n) { 
    if(n==0) return 1; 
    else return n * fact(n-1); 
} 

leen la implementación anterior, podrá comprender.

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); 
    } 
} 
+1

Háganme saber por qué el voto a favor? – SanA

+1

problably porque no explicaste nada, pero me gusta tu solución y he votado a favor. – another

10

Aquí es otra explicación de cómo el cálculo factorial utilizando recursividad obras.

Vamos a modificar ligeramente el código fuente:

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

Aquí está cálculo de 3! en detalles:

enter image description here

Fuente: RECURSION (Java, C++) | Algorithms and Data Structures

-1
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); 
} 
} 
+1

Agregue una explicación con la respuesta de cómo esta respuesta ayuda a OP a corregir el problema actual –

-1

Bueno, aquí está la lógica para encontrar factorial de un número utilizando la recursividad,

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; 
} 

Mientras tanto se puede hacer referencia this recursos para encontrar ejemplos sobre factorial de un número usando recursión.