數(shù)組的力量
??? 假如我們要精確計(jì)算一個(gè)很大的數(shù),比如說,256的階乘(結(jié)果有500多位),怎么辦?你會說,很好辦啊,從JDK 1.1起Java不是提供了一個(gè)java.math.BigInteger嗎?不錯,用BigInteger確實(shí)能解決問題。不過,如果沒有Sun給的這個(gè)class,僅僅靠Java最基本的那些類型,我們有沒有辦法來進(jìn)行計(jì)算呢?答案是,肯定是能嘛,要不然在BigInteger之前怎么辦。
方法之一就是用數(shù)組來表示。比如說:
??????????????????????? int[] data = new int[100];
??? 我們知道,一個(gè)int的最大值為2^31-1即2147483647(10位),如果我們把這100個(gè)int值串起來,我們就能表示一個(gè)1000位的數(shù)。這里我們就用這種方式來計(jì)算256的階乘(256!)。
??? 我們先分配100個(gè)int的數(shù)組,由于是static,所以每個(gè)int的初始值都是0。
??? 然后每個(gè)int表示6位數(shù),即最大值為999999。因?yàn)槲覀円龀朔ǎ绻oint的位數(shù)過大,如9位,那么999999999乘上一個(gè)數(shù),如100,它的值就大于了int的max值,造成溢出。所以int表示的位數(shù)需要根據(jù)需要仔細(xì)選擇。(用long來表示也同樣需要仔細(xì)權(quán)衡位數(shù))
??? 再定義一個(gè)num來表示我們占用的數(shù)組的int個(gè)數(shù)
??? 在乘法的時(shí)候,對每個(gè)占用的int中的數(shù)都要乘,然后一個(gè)一個(gè)地判斷每個(gè)int中的值是不是超出了6位:
??????????????????????? if (data[j]) > 1000000)
??? 如果超出了則需要進(jìn)位:
??????????????????????? data[k+1] += data[k]/1000000;
??????????????????????? data[k] %= 1000000;
一個(gè)個(gè)判斷,最后,如果最高位(即data[num])中的數(shù)值也超過了6位,我們就需要占用一個(gè)新的int,同樣地進(jìn)位,當(dāng)然也不要忘了給num加一。
??????????????????????? if (data[num] > 1000000) num++;
??? 最后,將我們的數(shù)組順序輸出即可。在輸出的時(shí)候需要小心的是,如果int中的值小于6位,如25,別忘了補(bǔ)上0,即000025,否則你會得到錯誤的答案的。
??? 完整的代碼如下:
package?tmp;
/**
?*
?*?@author?Stevech
?*/
public?class?BigNumbers?{
????static?int[]?data?=?new?int[100];
????
????/**?Creates?a?new?instance?of?BigNumers?*/
????public?static?void?main(String[]?args)?{
????????int?num?=?0;????//?占用的個(gè)數(shù)
????????data[0]?=?1;????//?0和1的階乘是1
????????
????????for?(int?i?=?2;?i?<?257;?i++)?{
????????????for?(int?j?=?0;?j?<?num?+?1;?j++)?{
????????????????data[j]?*=?i;????????//?對每個(gè)int中的數(shù)都乘上?i
????????????}
????????????for?(int?j?=?0;?j?<?num?+?1;?j++)?{
????????????????if?(data[j]?>?1000000)?{
????????????????????for?(int?k?=?j;?k?<?num?+?1;?k++)?{
????????????????????????if?(data[num]?>?1000000)?num++;
????????????????????????data[k+1]?+=?data[k]/1000000;????//?進(jìn)位
????????????????????????data[k]?%=?1000000;??????????????????//?進(jìn)位后的余數(shù)
????????????????????}
????????????????}
????????????}
????????}
????????System.out.println("占用的int數(shù):"?+?(num+1)?+?"\n值:");
????????System.out.print(data[num]);
????????for?(int?i?=?num-1;?i?>?-1;?i--)?{
????????????System.out.print(new?java.text.DecimalFormat("000000").format(data[i]));
????????}
????}
}
輸出結(jié)果為:/**
?*
?*?@author?Stevech
?*/
public?class?BigNumbers?{
????static?int[]?data?=?new?int[100];
????
????/**?Creates?a?new?instance?of?BigNumers?*/
????public?static?void?main(String[]?args)?{
????????int?num?=?0;????//?占用的個(gè)數(shù)
????????data[0]?=?1;????//?0和1的階乘是1
????????
????????for?(int?i?=?2;?i?<?257;?i++)?{
????????????for?(int?j?=?0;?j?<?num?+?1;?j++)?{
????????????????data[j]?*=?i;????????//?對每個(gè)int中的數(shù)都乘上?i
????????????}
????????????for?(int?j?=?0;?j?<?num?+?1;?j++)?{
????????????????if?(data[j]?>?1000000)?{
????????????????????for?(int?k?=?j;?k?<?num?+?1;?k++)?{
????????????????????????if?(data[num]?>?1000000)?num++;
????????????????????????data[k+1]?+=?data[k]/1000000;????//?進(jìn)位
????????????????????????data[k]?%=?1000000;??????????????????//?進(jìn)位后的余數(shù)
????????????????????}
????????????????}
????????????}
????????}
????????System.out.println("占用的int數(shù):"?+?(num+1)?+?"\n值:");
????????System.out.print(data[num]);
????????for?(int?i?=?num-1;?i?>?-1;?i--)?{
????????????System.out.print(new?java.text.DecimalFormat("000000").format(data[i]));
????????}
????}
}
占用的int數(shù):85
值:
85781777534284265411908227168123262515778152027948561985965565037726945255314
75893774402913604514084503758853423365843061571968346936964753222892884974260256
79637332563368786442675207626794560187968867971521143307702077526646451464709187
32610083287632570281898077367178145417025052301860849531906813825748107025281755
94594769870346657127381392862052347568082188607012036110831520935019474371091017
26968262861606263662435022840944191408424615936000000000000000000000000000000000
000000000000000000000000000000
posted on 2006-04-16 21:19 西門町學(xué)士 閱讀(1950) 評論(3) 編輯 收藏 所屬分類: Java