昨天晚上,到今天早上一直在想關於大整數操作,終於有收穫了
大整數的操作—階乘,加法,乘法-----比對C++與java
我個人覺得c++裏面的模板庫挺適合刷題的(acm);但是有一個缺點裏面不能存放很大的數;但是java可以,雖然我現在還沒有正式學過java,只是以前學過一點點,但是這已經足夠我去學習java的大數操作。我是一個初學者,如有錯誤請指教。
-
先來看一個題目
1441: N!
時間限制: 5 Sec 內存限制: 262 MB
提交: 9 解決: 7
題目描述
Given an integer N(0 ≤ N ≤ 10000), your task is to calculate N!
輸入
One N in one line, process to the end of file.
輸出
For each N, output N! in one line.
樣例輸入 [Copy](javascript:CopyToClipboard($(’#sampleinput’).text()))
1 2 3
樣例輸出 [Copy](javascript:CopyToClipboard($(’#sampleoutput’).text()))
1 2 6
-
這道題可以用C++來寫
思路很簡單,就是利用乘法運算中的豎式運算
這個題暴力是肯定不行,算到20多就炸了,這個題給的範圍到10000
所以,這個題運用到大數運算我們用數組a來存儲數據的每一位,用digit來表示當前的位數。 並初始化digit=1,a[0]=1;
n=2 a[0]=2
n=3 a[0]=6
n=4 a[0]=4 a[1]=2
n=5 a[0]=0 a[1]=2 a[2]=1
…
看到以上的數據肯定能明白 關鍵是怎麼實現的呢
存儲的數據是從個位開始存儲的,只需要temp=a[0]*i+up (i的取值範圍 1-n,up模擬的是的一個進位運算,例如n=5的時候 a[0]=(4 * 5)%10=0, 個位確定爲0,a[1]=(2 * 5+(20/10))%10=2,十位確定爲2 這個時候n=4的時候p=2,已經計算完了,這個時候up=12/10=1!=0 還需要再一次往前進位 a[p]=%10=1 p++ 位數爲3 結束)這裏插入一個視頻:
【算法教程】大數加法與大數階乘
-
AC代碼如下:
#include<bits/stdc++.h> using namespace std; const int Maxn=10e5; int a[Maxn]; // 用數組a來存儲每一位 int main() { int n; while(cin>>n) { memset(a,0,sizeof(a)); // 先初始化爲0; a[0]=1; // 先將a[0]賦值爲1; int p=1; // p代表數組a[p]還未開始儲存數字 for(int i=2;i<=n;i++) // 模擬n的階乘 { int up=0,temp=0; // temp臨時儲存a[j]*i的值,up代表進位值 for (int j=0;j<p;j++) // 將 a[j]與i相乘,此處爲一個遍歷; { temp=a[j]*i+up; up=temp/10; a[j]=temp%10; } while(up>0) // 如果up>0;說明往a[p]裏面存值了 { a[p++]=up%10; up/=10; } } for(int i=p-1;i>=0;i--) // 數組的逆序輸出; cout<<a[i]; cout<<endl; } return 0; }
-
下面是java的操作:
-
AC源碼:(ps:這是一段比較簡單的代碼就不多註釋了)
package javaLearn; import java.util.*; import java.math.*; public class bigInter { public static void main(String[] args) { Scanner cin=new Scanner(System.in); while (cin.hasNext()) { int n=cin.nextInt(); BigInteger sum=new BigInteger("1"); BigInteger flag=new BigInteger("1"); for(int i=0;i<n;i++) { sum=sum.multiply(flag); flag=flag.add(new BigInteger("1")); } System.out.println(sum); } } }
下面着重解釋一下:
java中有兩個類BigInteger和BigDecimal分別表示大整數類和大浮點數類,至於兩個類的對象能表示最大範圍不清楚,理論上能夠表示無線大的數,只要計算機內存足夠大。這兩個類都在java.math.*包中,因此每次必須在開頭處引用該包。
Ⅰ基本函數:
1.valueOf(parament); 將參數轉換爲制定的類型
比如 int a=3;
BigInteger b=BigInteger.valueOf(a);
則b=3;
String s=”12345”;
BigInteger c=BigInteger.valueOf(s);
則c=12345;
2.add(); 大整數相加
BigInteger a=new BigInteger(“23”);
BigInteger b=new BigInteger(“34”);
a.add(b);
3.subtract(); 相減
4.multiply(); 相乘
5.divide(); 相除取整
6.remainder(); 取餘
7.pow(); a.pow(b)=a^b
BigInteger
如果在操作的時候一個整型數據已經超過了整數的最大類型長度long的話,則此數據就無法裝入,所以,此時要使用BigInteger類進行操作。
BigInteger是在java.math包中。
-
樣例代碼:
//實例化一個大數字 BigInteger num1 = new BigInteger("4"); //將普通的數值轉換爲大數值 BigInteger num2 = BigInteger.valueOf(3); //取該大數字加2的操作 System.out.println("加法操作:"+ num1.add(num2)); //取該大數字減2的操作 System.out.println("減法操作:"+ num1.subtract(num2)); //取該大數字乘以2的操作 System.out.println("乘法操作:"+ num1.multiply(num2)); //取該大數字除以2的操作 System.out.println("除法操作:"+ num1.divide(num2)); //求餘 System.out.println("取餘:"+ num1.remainder(num2)); System.out.println("取餘:"+ num1.mod(num2)); //取該大數字的2次方 System.out.println("做2次方操作:"+ num1.pow(2)); //取該大數字的相反數 System.out.println("取相反數操作:"+ num1.negate()); //取最大公約數 System.out.println("取最大公約數:"+ num1.gcd(num2)); //取絕對值 System.out.println("取絕對值:"+ num1.abs()); //判斷相等 System.out.println("判斷相等:"+ num1.equals(num2)); //比較大小 System.out.println("比較大小:"+ num1.compareTo(num2)); //取較大值 System.out.println("取較大值:"+ num1.max(num2));
BigDecimal
使用此類可以完成大的小數操作,而且也可以使用此類進行精確的四捨五入,這一點在開發中經常使用。
對於不需要任何準確計算精度的程序可以直接使用float或double完成,但是如果需要精確計算結果,則必須使用BigDecimal類。
-
用法示例:
//實例化一個大數字 BigDecimal num1 = new BigDecimal("4.10"); //將普通的數值轉換爲大數值 BigDecimal num2 = BigDecimal.valueOf(3.9); //取該大數字加操作 System.out.println("加法操作:"+ num1.add(num2)); //取該大數字減操作 System.out.println("減法操作:"+ num1.subtract(num2)); //取該大數字乘操作 System.out.println("乘法操作:"+ num1.multiply(num2)); //取該大數字除操作 System.out.println("除法操作:"+ num1.divide(num2, 4, RoundingMode.HALF_UP)); //取該大數字的相反數 System.out.println("取相反數操作:"+ num1.negate()); //取絕對值 System.out.println("取絕對值:"+ num1.abs()); //判斷相等, 當且僅當兩個BigDecimal對象數值和精度scale均相等時才返回true System.out.println("判斷相等:"+ num1.equals(BigDecimal.valueOf(41, 1))); System.out.println("判斷相等:"+ num1.equals(BigDecimal.valueOf(410, 2))); //比較大小,僅比較兩個BigDecimal對象數值是否相等,忽略精度 System.out.println("比較大小:"+ num1.compareTo(BigDecimal.valueOf(41, 1))); System.out.println("比較大小:"+ num1.compareTo(BigDecimal.valueOf(410, 2))); //取較大值 System.out.println("取較大值:"+ num1.max(num2));
我以大整數爲例,用代碼示例一次:
package javaLearn; import java.util.*; import java.math.*; public class bigInter { public static void main(String[] args) { Scanner cin=new Scanner(System.in); while (cin.hasNext()) { BigInteger sum=cin.nextBigInteger(); BigInteger flag=cin.nextBigInteger(); System.out.println("乘法操作:"+sum.add(flag)); System.out.println("減法操作:"+ sum.subtract(flag)); System.out.println("乘法操作:"+ sum.multiply(flag)); System.out.println("除法操作:"+ sum.divide(flag)); System.out.println("取餘:"+ sum.remainder(flag)); System.out.println("取最大公約數:"+ sum.gcd(flag)); } } } // 輸出示例: 78 9 乘法操作:87 減法操作:69 乘法操作:702 除法操作:8 取餘:6 取最大公約數:3
-
有了java神器,再看一道題
大整數乘法
時間限制: 1 Sec 內存限制: 128 MB
提交: 393 解決: 181
題目描述
使用分治算法實現兩個大整數相乘。
輸入
兩個十進制大整數,滿足每一個整數長度爲2^n且兩個大整數的長度相等。(多組數據)
輸出
兩個大整數的乘積。
樣例輸入 [Copy](javascript:CopyToClipboard($(’#sampleinput’).text()))
1234 5678
樣例輸出 [Copy](javascript:CopyToClipboard($(’#sampleoutput’).text()))
7006652
-
有了java這波神操作,是不是很簡單,沒錯哦!就是這麼簡單
-
AC代碼:
import java.math.BigDecimal; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner cin=new Scanner(System.in); BigDecimal A,B; while(cin.hasNext()){ A=cin.nextBigDecimal(); B=cin.nextBigDecimal(); System.out.println(A.multiply(B)); } } }
好了,今天這波就介紹到這裏了。
喜歡的話,就點個贊吧!!!