CodeGym/Blog Java/Random-ES/Programa Java para factorial
Autor
Alex Vypirailenko
Java Developer at Toshiba Global Commerce Solutions

Programa Java para factorial

Publicado en el grupo Random-ES
Hoy vamos a hablar sobre factoriales y las formas más comunes de encontrar factoriales. Esta es una de las funciones más básicas que un programador necesita saber y poder trabajar con ella. Bueno, comencemos. El factorial del número n, denotado como n!, es el valor del producto (multiplicación) de todos los números naturales de 1 a n. Esto es lo que parece (vamos a refrescar tus conocimientos de matemáticas):
1! = 1 2! = 1 * 2 = 2 3! = 1 * 2 * 3 = 6 4! = 1 * 2 * 3 * 4 = 24 5! = 1 * 2 * 3 * 4 * 5 = 120
Y hay una pequeña regla más para el 0:
!0 = 1
Si queremos calcular la diferencia entre 6! y 4!:
6!-4! = 1⋅2⋅3⋅4⋅5⋅6 - 1⋅2⋅3⋅4 = 720 - 24 = 696
Veamos cómo se vería esto cuando se implemente en la programación. Exploraremos algunas formas de cómo hacer cálculos de factorial en Java.

Solución ordinaria en programa factorial

Aquí hay un programa factorial simple usando loop:
class FactorialExample{
 public static void main(String args[]){
  int i,fact=1;
  int number=7;// our number to do the necessary calculations in class Factorial
  for(i=1;i<=number;i++){
      fact=fact*i;
  }
  System.out.println("Factorial of "+number+" is: "+fact);
 }
}
Nuestra salida en la consola será:
Factorial de 7 es: 5040
Y un ejemplo más para aclarar las cosas:
public static int getFactorial(int f) {
  int result = 1;
  for (int i = 1; i <= f; i++) {
     result = result * i; // finding factorial of number using loops
  }
  return result;
}
Nada difícil aquí: usamos el número pasado como el tamaño de nuestro bucle, en el que multiplicamos por todos los números anteriores hasta llegar a f. Y en principal:
System.out.println(getFactorial(6) - getFactorial(4));
Probando el código, vemos que obtenemos el resultado deseado: 696.

solución recursiva

La recursividad ocurre cuando un método se llama a sí mismo. Tal método se llama método recursivo. Como regla general, consta de dos partes:
  1. Una condición de terminación: cuando se cumple la condición de terminación, el método debe dejar de llamarse a sí mismo y comenzar a pasar valores. Después de todo, si no hay una condición de terminación, entonces tendremos un ciclo infinito, con el método llamándose a sí mismo repetidamente hasta que obtengamos un StackOverflowError .
  2. Cualquiera que sea la lógica que requiera la situación más una llamada recursiva, pero con un valor de entrada diferente.
Encontrar el factorial en Java es un ejemplo perfecto de cuándo usar la recursividad:
public static int getFactorial(int f) { // finding factorial of number using recursive solution
  if (f <= 1) {
     return 1;
  }
  else {
     return f * getFactorial(f - 1);
  }
}
Nuestra condición de terminación de la recursividad será cuando lleguemos a 1. Si el parámetro no es 1, entonces multiplicamos el valor actual por el resultado de la siguiente llamada recursiva al método (al que le pasamos el valor actual menos 1).

Solución con un Stream

Cualquiera que no esté familiarizado con la funcionalidad Stream de Java, o cualquiera que quiera refrescar su memoria, se beneficiará de leer aquí .
public static int getFactorial(int f) { // finding factorial of number using Stream
  if (f <= 1) {
     return 1;
  }
  else {
     return IntStream.rangeClosed(2, f).reduce((x, y) -> x * y).getAsInt();
  }
}
Aquí usamos la clase especial IntStream , que nos brinda capacidades adicionales cuando trabajamos con un flujo de valores int. Para crear una transmisión de este tipo, usamos su método estático rangeClosed , que genera valores de 2 a f, inclusive, en incrementos de 1. Luego, usamos el método reduce para combinar todos los valores. Más concretamente, le mostramos cómo queremos combinar los valores. Finalmente, obtenemos el valor resultante usando el método terminal getAsInt .

Usando BigInteger

En Java, la clase BigInteger se usa a menudo para manejar números, especialmente números GRANDES. De hecho, si usamos int , entonces el factorial máximo que podemos manejar sin pérdida de datos es 31. Para el tipo de datos largo , el factorial máximo es 39. Pero, ¿y si necesitamos el factorial de 100? Adaptemos las soluciones anteriores a BigInteger.Programa Java para factorial - 2

solución ordinaria

public static BigInteger getFactorial(int f) { // finding factorial of number using BigInteger
  BigInteger result = BigInteger.ONE;
  for (int i = 1; i <= f; i++)
     result = result.multiply(BigInteger.valueOf(i));
  return result;
}
El algoritmo es esencialmente el mismo, pero aquí usamos las capacidades de BigInteger: BigInteger.ONE es el valor inicial 1, y multiplicar() se usa para multiplicar el valor factorial anterior y el número actual.

solución recursiva

public static BigInteger getFactorial(int f) {
  if (f <= 1) {
     return BigInteger.valueOf(1);
  }
  else {
     return BigInteger.valueOf(f).multiply(getFactorial(f - 1));
  }
}
La lógica general de la solución no cambia, excepto que se agregan algunos métodos para trabajar con BigInteger.

Solución con un Stream

public static BigInteger getFactorial(int f) {
  if (f < 2) {
     return BigInteger.valueOf(1);
  }
  else {
     return IntStream.rangeClosed(2, f).mapToObj(BigInteger::valueOf).reduce(BigInteger::multiply).get();
  }
}
Todo es esencialmente igual, pero con BigInteger. La clase Stream nos proporciona el método mapToObj , que usamos para convertir valores int a BigInteger para luego multiplicarlos entre sí usando el método de multiplicación (y se agregó get() para obtener un objeto del contenedor opcional ). Si ejecutamos cualquiera de estos tres métodos con un argumento de 100, evitaremos un desbordamiento de pila y obtendremos el resultado correcto:
9332621544394415268169923885626670049071596826438162146859296389521759999322991560894146397615651828625369792082722375825 11852109168640000000000000000000000000
Comentarios
  • Populares
  • Nuevas
  • Antiguas
Debes iniciar sesión para dejar un comentario
Esta página aún no tiene comentarios