兩個大數相減

最近,在網上看到一篇講大數相減的文章,講的思想是對的,但是代碼編寫不正確,就對其進行了改正。

參考文章鏈接:http://www.cnblogs.com/ballwql/archive/2013/04/20/3032090.html

大數相減與大數相加相比,需要考慮借位問題。處理借位需要考慮二種情況,假設被減數爲Sub1,減數爲Sub2,這些都是以字符串形式存儲的大數。則大致要考慮二種情況的借位: 

 1)Length of Sub1 is greater or equal to Length of Sub2: 此時需要考慮兩種借位:一種是Sub1大數大於Sub2大數,則Sub1最高位(Sub1首位置)無需再進一步借位,此種狀況比較好處理;另一種是Sub1大數小於Sub2大數,則Sub1最高位還需進一步借位,此種情況處理稍微複雜,在下面將展開討論.

2)Length of Sub1 isless than Length of Sub2: 此種情況即Sub1最高位還需進一步借位情況,我們在此假設Sub1長度不足Sub2長度的部分填充0,以"123"(sub1) -"456789"(sub2)爲例,如下簡圖所示,最終結果應該爲"456666",還要加負號表示結果爲負數。在此過程中還要引入一個基數作爲調整,基數設定原理是以第一種情況所算出的最終值爲參考,如下圖參考基數所述,其實只要理解相減過程,此步不難理解。



/**
* 大數相減,但這兩個大數是正整數
* 暫時沒有考慮有負數的情況和其他非法輸入的情況
* 
*/

#include <iostream>
#include <string.h>
using namespace std;
const int N=1002;

void Sub(char *p1,char *p2,int *p3)
{
    int i,j,k=0;
    
    int bit=0,t=0; //bit:表示借位,1:表示需要借位,0:表示不需要借位。t:存儲中間計算的位相減值
    int len1=strlen(p1);  //被減數的長度
    int len2=strlen(p2); //減數的長度
	bool isBeginning0 = true;
    
    for(i=len1-1,j=len2-1;i>=0 && j>=0;--i,--j) //此爲循環遍歷兩數,分別對位進行相減操作
    {
        t=(p1[i]-'0')-(p2[j]-'0')-bit;    //計算兩個位之間的差值,同時要考慮借位
        
        if(t<0)  //如果t小於0,表示需要借位,bit賦值爲1,且最終相減結果需加10作爲調整並存儲到p3數組中,自己用筆畫一下就好理解.
        {
			bit=1;
			//例:123-456,t相減實際值分別爲-3(3-6-0(bit)),-4(2-5-1(bit)),-4(1-4-1(bit)),加10調整後爲:
			// 7,6,6,由於最高位相減後還bit爲1即還需借位,  因此還需調整,轉換爲第一種情況,即用1000-667=333,且結果爲負    
            p3[k++]=t+10;        
        }
        else
        {
            bit=0; //相減爲正,則無需調整,直接將t賦給p3對應位。
            p3[k++]=t;
        }   
    }

	//strlen(p1)>strlen(p2) ,result is greater than zero
    while(i>=0) 
    {
        t=p1[i]-'0'-bit;
        if(t<0)
        {
            bit=1;
            p3[k++]=t+10;
        }
        else
        {
            bit=0;
            p3[k++]=t;
        }
        i--;
    }

	//strlen(p1)<strlen(p2),result is less than zero
    while(j>=0) 
    {
     
		t = 0 - (p2[j]-'0') - bit;
		if(t<0)
		{
			bit = 1;
			p3[k++] = t + 10;
		}
		else
		{
			bit = 0;
			p3[k++] = t;
		}
		j--;
    }

	//對仍有進位的情況考慮,主要分兩種:
	//一種是strlen(p1)==strlen(p2),但p1<p2
	//另一種是strlen(p1)<strlen(p2),p1<p2
	//這兩種情況都是bit爲1
	//但要注意1點:從低位到高位求減法時,要從不爲0的位開始減
    if(bit==1)  
    {
		for(j = 0; j < k; ++j)
			if(p3[j] != 0)
				break;

        p3[j]=10-p3[j];
        for(i=j+1;i<k;++i)
        {
            p3[i]=10-p3[i]-bit;
        }        
    }

    if(bit==1)
        cout<<"-";

	//數字前面的0不輸出,如-09,輸出-9
    for(i=k-1;i>=0;--i)
	{
		if(isBeginning0 && p3[i] != 0)
			isBeginning0 = false;
		if(!isBeginning0)
			cout<<p3[i];
	}
    cout<<endl;
}

int main()
{
    char c1[N],c2[N];
    int a[N];
    int i,j;

    while(cin>>c1>>c2)
    {
        memset(a,0,sizeof(a));
        Sub(c1,c2,a);
    }

    return 0;
}

運行結果:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章