1. 程式人生 > 其它 >關於大整數減法的思路及程式碼實現

關於大整數減法的思路及程式碼實現

技術標籤:筆記演算法c語言

大整數減法

例題

給定兩個整數n ,m ( 0 ≤ n,m ≤ 10^100),求第一個數減去第二個數的結果。

樣例輸入

5179812595970305437756730080472635223110
82810385188752593217702944391101384413943919290511

樣例輸出

-82810385183572780621732638953344654333471284067401

解題思路

資料輸入與儲存

對於這樣兩個大整數,已經遠遠超過了整型可以儲存的範圍,所以我們用兩個整型陣列來儲存它的每一位。

輸入也是個麻煩,這裡採用的是另外定義兩個字元陣列把兩個數字當作兩個字串直接用 %s 就可以輸入了,然後就是用迴圈每一位減去字元 ‘0’ 後存入陣列中

char a[105];
char b[105];
int p1[105];
int p2[105];
int ans[105];
scanf("%s", a);
scanf("%s", b);
p1[0] = strlen(a); // p1[0]儲存著p1的位數,p2[0]亦如此
p2[0] = strlen(b);
for (int i = 1; i <= p1[0]; i++)
{
    p1[i] = a[p1[0] - i] - '0';  // 從低到高倒著存方便處理最終結果位數變小的情況
}
for (int i = 1; i <= p2[0]; i++)
{ p2[i] = b[p2[0] - i] - '0'; }

計算部分

比較大小: 鑑於被減數可能比減數小,我們先比較兩個數哪個大決定是否要輸出負號;

if(p1[0] == p2[0])  //比較兩個數位數是否相等,若相等則從高到低位逐位判斷大小
{
    for (int i = p1[0]; i > 0; i--)
    {
        if(p1[i] != p2[i])
        {
            cha = p1[i] > p2[i] ? 1 : -1;
            break;
        }
        if(p1[0] ==
p2[0]) cha = 0; } } else if(p1[0] > p2[0]) //cha為標誌位被減數大:1,減數大:-1,相等:0 cha = 1; else cha = -1;

逐位相減: 用大的數逐位減去小的數,也就是大數的個位減小數的個位,十位減小數的十位;

處理借位: 從低到高逐位判斷是否小於 0 ,小於 0 則向高一位借位,即該位加10、高位減 1,即可得到結果。

for (int i = 1; i <= a[0]; i++)
{
    ans[i] += a[i] - b[i]; //逐位相減後存入答案陣列
    if (ans[i] < 0) //處理借位
    {
        ans[i] += 10;
        ans[i + 1]--;
    }
}

計算答案位數: 計算最終答案的位數以便於輸出,從高到低逐位判斷是否為0,第一個不為零的設為答案的位數。

ans[0] = a[0];
for (int i = ans[0]; i > 0; i--)
{
    if(ans[i] != 0)
        break;
    else
        ans[0] = i - 1;
}

完整程式碼

#include <stdio.h>
#include <string.h>
char a[105];
char b[105];
int p1[105];
int p2[105];
int ans[105];
int func2(int *a, int *b) 
{
	
	for (int i = 1; i <= a[0]; i++)
	{
		ans[i] += a[i] - b[i];
		if (ans[i] < 0)
		{
			ans[i] += 10;
			ans[i + 1]--;
		}
	}
	ans[0] = a[0];
	for (int i = ans[0]; i > 0; i--)
	{
		if(ans[i] != 0)
			break;
		else
			ans[0] = i - 1;
	}
	return 0;
}
int func(int *p1, int *p2)
{
	int cha = 1;
	if(p1[0] == p2[0])
	{
		for (int i = p1[0]; i > 0; i--)
		{
			if(p1[i] != p2[i])
			{
				cha = p1[i] > p2[i] ? 1 : -1;
				break;
			}
			if(p1[0] == p2[0])
				cha = 0;
		}
	}
	else if(p1[0] > p2[0])
		cha = 1;
	else
		cha = -1;

	switch (cha)
	{
	case 0:
		break;
	case 1:
		func2(p1, p2);
		break;
	case -1:
		func2(p2, p1);
		break;
	}
	return cha;
}
int main()
{
    scanf("%s", a);
	scanf("%s", b);
	p1[0] = strlen(a); 
	p2[0] = strlen(b);
	for (int i = 1; i <= p1[0]; i++)
	{
		p1[i] = a[p1[0] - i] - '0';
	}
	for (int i = 1; i <= p2[0]; i++)
	{
		p2[i] = b[p2[0] - i] - '0';
	}

	if(func(p1, p2) == -1) printf("-");
	
	for (int i = 1; i <= ans[0]; i++)
	{
		printf("%d", ans[ans[0] - i + 1]);
	}
	return 0;
}