1. 程式人生 > >大數加減法

大數加減法

大數儲存:由於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的情況。