[問題描述]
編寫程序實現兩個超長正整數(每個最長80位數字)的減法運算。
[輸入形式]
從鍵盤讀入兩個整數,要考慮輸入高位可能為0的情況(如00083)
1.第一行是超長正整數A;
2.第二行是超長正整數B;
[輸出形式]
輸出只有一行,是長整數A減去長整數B的運算結果,從高到低依次輸出各位數字。要求: 若結果為0,則只輸出一個0;否則輸出的結果的最高位不能為0,并且各位數字緊密輸出。
[輸入樣例]
234098
134098703578230856
[輸出樣例]
-134098783577995958
[樣例說明]
進行兩個正整數減法運算,234098 - 134098703578230056 = - 134098703577995958。
[思路分析]
題目要求為超長正整數的減法運算,容易知道整型變量無法完成此操作,所以大體思路:考慮用兩個字符數組儲存,用兩數組的ASCII碼進行運算,然后判斷符號,進行輸出。
具體步驟:
- 先定義兩個字符數組代替整型儲存這兩個整數;
- 考慮字符數組ASCII碼相減需要對齊位數,排除數字開頭為0的情況,于是先用循環將每個數組前面的0都消去,使得兩數組代表的數字都是非零數開頭的;
- 由于字符數組ASCII碼相減從低位開始會更為容易,于是將處理0以后的兩個數組均調用逆序函數逆序存放,使得對應的數字為低位在前高位在后,由低到高依次運算,這樣容易處理借位情況;
- 定義字符數組的運算函數,將兩個字符數組對應位的ASCII碼分別相減,直接將結果保存在整型數組中,通過判斷整型數組每個數的正負來確定是否借位,如果小于0則借位,則它本身加十,并且高位即下一個數減去一來借位,執行完此操作,整型數組內存放的即超長整數的差的絕對值的逆序;
- 由于2)已經將兩個字符數組開頭的零去掉了,因此,位數不同時可以很容易由字符數組的長度來判斷兩個整數的大小,位數相同的時可以通過第一個不同字符的ASCII碼的數值的大小來判斷兩個整數的大小,通過不同的傳遞順序把兩個字符數組傳遞給運算函數,并判斷輸出時是否加負號;
- 確定正負號以后的最后一步即將之前保存的整型數組按照倒序輸出在符號后邊即可。
[代碼實現]
#include<stdio.h>
#include<string.h>
int c[100];
int judge(char a[],char b[])
{if (strlen(a) > strlen(b))return 1;else if (strlen(a) < strlen(b))return 0;elsefor (int i = 0; i < strlen(a); i++)if (a[i] > b[i])return 1;return 0;
}void minus(char a[], char b[])
{char t;for (int i = 0; i < strlen(a) / 2; i++){t = a[i];a[i]=a[strlen(a) - 1 - i];a[strlen(a) - 1 - i] = t;}for (int i = 0; i < strlen(b) / 2; i++){t = b[i];a[i] = a[strlen(b) - 1 - i];a[strlen(b) - 1 - i] = t;}for(int i=0;i<strlen(a);i++){if (i < strlen(b))c[i] = a[i] - b[i];elsec[i] = a[i] - '0';}for (int i = 0; i < strlen(a) - 1; i++)if(c[i]<0){c[i] += 10;c[i + 1] -= 1;}
}void deletechar(char a[])
{int t = 0, len;while (a[t] == '0')t++;len = strlen(a) - t;for (int i = 0; i <= len; i++)a[i] = a[i + t];
}
int main()
{char a[100], b[100];gets(a);gets(b);deletechar(a);deletechar(b);if (judge(a, b))minus(a, b);else{printf("-");minus(b, a);}int i = 100;while (c[i] == 0 && i != 0)i--;for (int j = i; j >= 0; j--)printf("%d", c[j]);
}