国产成人毛片视频|星空传媒久草视频|欧美激情草久视频|久久久久女女|久操超碰在线播放|亚洲强奸一区二区|五月天丁香社区在线|色婷婷成人丁香网|午夜欧美6666|纯肉无码91视频

用Java實現(xiàn)大數(shù)階乘

隨著計算機硬件的不斷升級,大數(shù)計算已不再是問題。但在某些場合下,我們還是需要自己編寫程序來處理大數(shù)計算問題。比如在一些面試題中,可能會涉及到大數(shù)階乘的計算問題。本文將介紹使用Java來實現(xiàn)大數(shù)階乘的方

隨著計算機硬件的不斷升級,大數(shù)計算已不再是問題。但在某些場合下,我們還是需要自己編寫程序來處理大數(shù)計算問題。比如在一些面試題中,可能會涉及到大數(shù)階乘的計算問題。本文將介紹使用Java來實現(xiàn)大數(shù)階乘的方法。

計算Java提供的數(shù)據(jù)類型可以處理的最大范圍

在開始介紹大數(shù)階乘的具體實現(xiàn)前,我們需要先了解一下Java提供的數(shù)據(jù)類型可以處理的數(shù)據(jù)范圍。Java中提供了兩種基本數(shù)據(jù)類型:int和long。它們分別占用4個字節(jié)和8個字節(jié)。它們所能表示的數(shù)值范圍如下:

- int:-2,147,483,648 ~ 2,147,483,647,最多可計算12的階乘。

- long:-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807,最多可計算20的階乘。

如果我們要計算更大范圍的數(shù)字的階乘(例如50的階乘),就需要使用自定義的數(shù)字類型來表示這個數(shù)字了。

使用鏈表表示法自定義數(shù)字類型

為了表示一個大數(shù),我們可以使用鏈表的方式,將每一位數(shù)字從低到高存儲到鏈表中。如下所示:

數(shù)字:1234 鏈表表示為:1->2->3->4

數(shù)字:788996 鏈表表示為:7->8->8->9->9->6

下面是用Java代碼實現(xiàn)的鏈表節(jié)點類:

private static class ListNode {

int val; // 鏈表節(jié)點的值

ListNode next; // 下一個節(jié)點

public ListNode(int val) {

val;

}

// 重新 toString 方法,方便最后輸出整個鏈表

@Override

public String toString() {

StringBuilder b new StringBuilder();

(val);

ListNode nextNode next;

while (null ! nextNode) {

(",").append();

nextNode ;

}

return ();

}

}

實現(xiàn)大數(shù)相乘

在實現(xiàn)大數(shù)階乘之前,我們需要先掌握如何實現(xiàn)大數(shù)相乘。我們可以把一個大于等于10的數(shù)字拆分為多個小于10的數(shù)字,然后對每個小數(shù)字分別進行計算,最后將它們的結(jié)果相加。具體步驟如下:

- 將數(shù)字進行拆分,將一個大于等于10的數(shù)字,拆分為多個小于10的數(shù)字。

- 將每一個小于10的數(shù)字和我們的大數(shù)相乘。

- 將相乘的結(jié)果進行累加,即得到最終結(jié)果。

拆分數(shù)字的具體實現(xiàn)可以參考下面的代碼:

private int[] scatterNumber(int num) {

// 注意要除以9.0,否則兩個整數(shù)相除一定返回一個整數(shù)

int resultLength (int) Math.ceil(num / 9.0);

int[] result new int[resultLength];

int index 0;

while (num > 10) {

result[index] 9;

num num - 9;

index ;

}

if (num > 0) {

result[index] num;

}

return result;

}

實現(xiàn)大數(shù)相乘的代碼如下:

private ListNode multipleSingleNum(ListNode ln, int num) {

ListNode result new ListNode(0);

ListNode currentNode result;

int carryBit 0; // 進位

while (null ! ln) {

int mVal * num carryBit;

carryBit mVal / 10;

mVal mVal % 10;

ListNode theNode new ListNode(mVal);

theNode;

currentNode ;

ln ;

}

// 注意最后要看看是否還有有效的進位沒有處理

if (carryBit > 0) {

new ListNode(carryBit);

}

return ;

}

private ListNode multipleNumber(ListNode ln, int num) {

// 將數(shù)字進行拆分

int[] allUsedNums scatterNumber(num);

ListNode result new ListNode(0);

for(int usedNum : allUsedNums) {

// 將每一個小于10的數(shù)字和我們的大數(shù)相乘

ListNode mulResult multipleSingleNum(ln, usedNum);

// 將相乘的結(jié)果進行累加

result addTwoNumbers(result, mulResult);

}

return result;

}

當兩個大數(shù)長度不一致時,我們可以在短的那條大數(shù)前補0,使它與另一個大數(shù)長度一樣。具體實現(xiàn)可以參考下面的代碼:

private ListNode addTwoNumbers(ListNode l1, ListNode l2) {

int firstNodeVal ;

int carryBit firstNodeVal / 10; // 進位

firstNodeVal firstNodeVal % 10; // 當前位的值

ListNode result new ListNode(firstNodeVal); // 最后的計算結(jié)果

ListNode computePoint result; // 指向當前的計算節(jié)點

l1 ; // 移到下一個節(jié)點

l2 ; // 移到下一個節(jié)點

while (null ! l1 || null ! l2) {

int l1Val null l1? ;

int l2Val null l2? ;

int sum l1Val l2Val carryBit; // 計算和,要加上進位

carryBit sum / 10; // 重新計算進位

sum sum % 10; // 當前位的和

new ListNode(sum);

computePoint ; // 移到下一個節(jié)點

l1 null l1? ; // 移到下一個節(jié)點

l2 null l2? ; // 移到下一個節(jié)點

}

// 如果最后進位有結(jié)余,則需要將其設置到新節(jié)點中

if (carryBit > 0) {

new ListNode(carryBit);

}

return result;

}

測試

我們分別計算10、20、50的階乘,并驗證運行結(jié)果是否正確。具體代碼如下:

public static void main(String[] args) {

Solution solution new Solution();

int n1 10;

ListNode result1 solution.factorial(n1);

(n1 "! " ());

int n2 20;

ListNode result2 solution.factorial(n2);

(n2 "! " ());

int n3 50;

ListNode result3 solution.factorial(n3);

(n3 "! " ());

}

輸出結(jié)果如下:

10! 3628800

20! 2432902008176640000

50! 30414093201713378043612608166064768844377641568960512000000000000

以上就是使用Java實現(xiàn)大數(shù)階乘的方法。通過使用鏈表表示法和自定義的大數(shù)計算方法,我們可以輕松地處理大數(shù)計算問題,并得到準確的結(jié)果。

標簽: