大數加減法
阿新 • • 發佈:2018-12-18
大數儲存:由於x的位數最大為400位,我們不能用現有的int,longlong,double等資料型別進行儲存。一般儲存大數的方法是用一個字串來表示。
方法:模擬小學生算術。
在這裡我們先討論全為正整數的情況哈。
加法
123
+ 23
146
對應位數相加,最後再進位,滿十進一,為了方便計算,我們採用低位在前,高位在後的逆序儲存相加後的結果。(兩個數相加結果最大隻會比較大的多一位)
123456+5677
6 | 5 | 4 | 3 | 2 | 1 |
7 | 7 | 6 | 5 | ||
13 | 12 | 10 | 8 | 2 | 1 |
C語言實現
#include<stdio.h> #include<string.h> const int maxn=1000+7; using namespace std; void plus(int a[],int b[],int len) { //給每一位作加法,滿十進一 for(int i=0;i<len;i++) { a[i]+=b[i]; if(a[i]>=10) { a[i]-=10; a[i+1]+=1; } } //去掉字首0 int flag=0; for(int i=len;i>=0;i--) { if(a[i]!=0) { flag=1; for(i=i;i>=0;i--) printf("%d",a[i]); break; } } if(flag==0) printf("0"); printf("\n"); } int main() { char str2[maxn],str1[maxn]; int a[maxn],b[maxn]; int n,len1,len2,len; scanf("%d",&n); getchar(); while(n--) { memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); scanf("%s%s",str1,str2); len1=strlen(str1); len2=strlen(str2); if(len1>len2) len=len1; else len=len2; for(int i=0;i<len1;i++) //將字元編碼的數字轉換為對應的數 { a[i]=str1[len1-i-1]-'0'; } for(int i=0;i<len2;i++) { b[i]=str2[len2-i-1]-'0'; } plus(a,b,len); } return 0; }
Java實現
import java.math.BigInteger; import java.util.Scanner; public class 大數加法 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n =sc.nextInt(); for(int i=1;i<=n;i++){ BigInteger a = sc.nextBigInteger(); BigInteger b = sc.nextBigInteger(); System.out.println(a+" + "+b+" = "+a.add(b)); } } }
大數減法
和大數加法原理類似,對應位數相減,最後小於0的加10,它的後一位-1;
654321-2042
1 | 2 | 3 | 4 | 5 | 6 |
2 | 4 | 0 | 2 | ||
-1 | -2 | 3 | 2 | 5 | 6 |
該規則遵守大數減小數,因此先比較兩個字串的長度,長度長的數字大,長度相等,比較高位,如果相等依次類推。
我們可以把大數-小數直接進行上述的規則計算,小數-大數,可以交換他們的位置,變成為大數減小數,並在最前面加上負號。
c語言實現
#include<stdio.h>
#include<string.h>
const int maxn=1000+7;
using namespace std;
void sub(int a[],int b[],int len)
{
for(int i=0;i<len;i++)
{
a[i]-=b[i];
if(a[i]<0)
{
a[i]+=10;
a[i+1]-=1;
}
}
int flag=0;//刪除字首0
for(int i=len;i>=0;i--)
{
if(a[i]!=0)
{
flag=1;
for(i=i;i>=0;i--)
printf("%d",a[i]);
break;
}
}
if(flag==0)//結果為0時
printf("0");
printf("\n");
}
int main()
{
char str1[maxn],str2[maxn];
int len1,len2,a[maxn],b[maxn];
while(~scanf("%s%s",str1,str2))
{
len1=strlen(str1);
len2=strlen(str2);
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(int i=0;i<len1;i++)
{
a[i]=str1[len1-i-1]-'0';
}
for(int i=0;i<len2;i++)
{
b[i]=str2[len2-i-1]-'0';
}
if(len1>len2) //若減數長度>被減數,按照規則直接減
sub(a,b,len1);
else if(len1<len2)//若減數長度<被減數,用被減數-減數
{
printf("-");
sub(b,a,len2);
}
else //若減數長度==被減數長度,判斷兩個數每位的大小
{
for(int i=len1-1;i>=0;i--)//判斷每一位兩個數的大小
{
if(a[i]==b[i])
continue;
if(a[i]>b[i])//即減數大
{
sub(a,b,len1);
break;
}
if(a[i]<b[i])//即被減數大
{
printf("-");
sub(b,a,len1);
break;
}
}
}
}
return 0;
}
Java實現
import java.math.BigInteger;
import java.util.Scanner;
public class 大數加法 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n =sc.nextInt();
for(int i=1;i<=n;i++){
BigInteger a = sc.nextBigInteger();
BigInteger b = sc.nextBigInteger();
System.out.println(a+" - "+b+" = "+a.subtract(b));
}
}
}
我寫的這個只能算a>b的情況。