CodeGym /Java Blog /Toto sisi /階乘的Java程序
John Squirrels
等級 41
San Francisco

階乘的Java程序

在 Toto sisi 群組發布
今天我們將討論階乘和最常見的求階乘的方法。這是程序員需要了解並能夠使用的最基本的功能之一。好吧,讓我們開始吧。數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