CodeGym /Java 博客 /随机的 /阶乘的Java程序
John Squirrels
第 41 级
San Francisco

阶乘的Java程序

已在 随机的 群组中发布
今天我们将讨论阶乘和最常见的求阶乘的方法。这是程序员需要了解并能够使用的最基本的功能之一。好吧,让我们开始吧。数n的阶乘,记作n!,是从1到n的所有自然数的乘积(乘法)的值。这是它的样子(让我们刷新你的数学知识):
1!= 1 2!= 1 * 2 = 2 3!= 1 * 2 * 3 = 6 4!= 1 * 2 * 3 * 4 = 24 5!= 1 * 2 * 3 * 4 * 5 = 120
还有一个关于 0 的小规则:
!0 = 1
如果我们要计算6之间的差异!和 4!:
6!-4!= 1·2·3·4·5·6 - 1·2·3·4 = 720 - 24 = 696
让我们看看在编程中实现时会是什么样子。我们将探讨如何在 Java 中计算阶乘的几种方法。

阶乘程序中的普通解

这是一个使用循环的简单阶乘程序:

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);    
 }  
}
我们在控制台上的输出将是:
7 的阶乘是:5040
还有一个例子来解决问题:

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;
}
这里没什么困难:我们使用传递的数字作为循环的大小,在循环中我们乘以所有前面的数字,直到得到 f。主要是:

System.out.println(getFactorial(6) - getFactorial(4));
测试代码,我们看到我们得到了想要的结果:696。

递归求解

递归发生在方法调用自身时。这种方法称为递归方法。通常,它由两部分组成:
  1. 终止条件——当满足终止条件时,该方法应停止调用自身并开始向上传递值。毕竟,如果没有终止条件,那么我们将有一个无限循环,方法会反复调用自身,直到我们得到StackOverflowError
  2. 无论情况需要什么逻辑加上递归调用,但具有不同的输入值。
在 Java 中查找阶乘是何时使用递归的完美示例:

public static int getFactorial(int f) { // finding factorial of number using recursive solution
  if (f <= 1) {
     return 1;
  }
  else {
     return f * getFactorial(f - 1);
  }
}
我们的递归终止条件是当我们达到 1 时。如果参数不是 1,那么我们将当前值乘以对该方法的下一次递归调用的结果(我们将当前值减 1 传递给该方法)。

流解决方案

任何不熟悉 Java 的 Stream 功能的人,或任何想重温记忆的人,都将从阅读此处受益。

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();
  }
}
这里我们使用特殊的IntStream类,它在处理 int 值流时为我们提供了额外的功能。为了创建这样一个流,我们使用它的静态rangeClosed方法,它生成从 2 到 f 的值,包括 1,增量为 1。接下来,我们使用 reduce 方法来组合所有值。更具体地说,我们向它展示了我们希望如何组合这些值。最后,我们使用终端getAsInt方法获取结果值。

使用大整数

在 Java 中,BigInteger类通常用于处理数字,尤其是 BIG 数字。事实上,如果我们使用int,那么我们可以在不丢失数据的情况下处理的最大阶乘是 31。对于long数据类型,最大阶乘是 39。但是如果我们需要 100 的阶乘呢?让我们将以前的解决方案改编为 BigInteger。阶乘的 Java 程序 - 2

普通溶液


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;
}
算法本质上是一样的,只不过这里我们使用了BigInteger的能力:BigInteger.ONE是起始值1,multiply()用于将前一个阶乘值与当前数相乘。

递归求解


public static BigInteger getFactorial(int f) {
  if (f <= 1) {
     return BigInteger.valueOf(1);
  }
  else {
     return BigInteger.valueOf(f).multiply(getFactorial(f - 1));
  }
}
解决方案的一般逻辑没有改变,只是添加了一些方法来处理 BigInteger。

流解决方案


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();
  }
}
一切本质上都是一样的,但使用了 BigInteger。Stream 类为我们提供了mapToObj方法,我们使用该方法将 int 值转换为 BigInteger,然后使用 multiply方法将它们与自身相乘(并添加了get()以从Optional包装器获取对象)。如果我们使用参数 100 运行这三种方法中的任何一种,那么我们将避免堆栈溢出并获得正确的结果:
9332621544394415268169923885626670049071596826438162146859296389521759999322991560894146397615651828625369792082722375825 1185210916864000000000000000000000000
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION