題目鏈接:P2142 高精度減法 - 洛谷
1.題目??
2.算法原理
解法:模擬列豎式計算的過程
- 先用字符串讀入,然后拆分每一位,逆序放進數組中
- 利用數組,模擬列豎式減法的過程
在這兩步之前要多加一步,在模擬解法的過程,一定是一個較大的數減去較小的數,如果是較小的數減較大的數,列豎式計算過程會出錯的,如果這道題給的是99-123,此時要把它轉換成123-99,在最終輸出結果之前先輸出一個負號就可以了,所以我們要先處理一個情況,先比較大小,然后用較大的數減去較小的數
有一個問題,題目給的這兩個數是用字符串來存的,如果直接用字符串比較大小肯定出錯,它涉及字典序vs數的大小的問題,此時有兩個數101和99,如果是數的話, 101一定大于99 ,但字符串就不一定了,最終比較結果是99大于101,因為比較字符串的時候是按照字典序來比較的,它的比較方式是我管你這串字符串的長度是多少,直接從最高位開始比較,‘9’這個字符是大于‘1’字符的,所以99字符大于101字符串,這不是我們想要的,處理這種情況,可以在用字符串比較之前,先比較一下長度,長度較長的數一定是大的,如果兩個字符串長度相等,再按照字典序的方式來比較就可以了
?還有如果是997-996,結果等于1,因為前導0是要把它刪掉的,但此時lc的長度等于3,lc原本指向-1,把前導0去掉后,lc應該指向下標2,所以我們可以判斷下lc-1這個位置如果是0,就讓lc- -,當他下一個位置是1的時候,讓他停下就可以;還有一種情況,如果是999-999,最終的結果是000,lc下標2的時候,lc-1的位置還是0,就不能再減了,因為你最低限度這里面是要存一個0的,所以lc- -的時候要判斷一下,lc大于1的時候再去- -,因為lc如果等于1的話,這里即使只剩一個0,lc也不能再減了
代碼:
#include <iostream>
using namespace std;const int N = 1e6 + 10;
int a[N], b[N], c[N];
int la, lb, lc; //分別標記abc數組長度// 高精度加法的模版 - c = a + b;
void add(int c[], int a[], int b[])
{for (int i = 0; i < lc; i++){c[i] += a[i] + b[i]; // 對應位相加,再加上進位 9+4=13c[i + 1] += c[i] / 10; // 處理進位 13/10=1c[i] %= 10; // 處理余數 13%10=3}if (c[lc]) lc++;
}int main()
{string x, y; cin >> x >> y;// 1. 拆分每一位,逆序放在數組中la = x.size(); lb = y.size(); lc = max(la, lb);for (int i = 0; i < la; i++) a[la - 1 - i] = x[i] - '0';for (int i = 0; i < lb; i++) b[lb - 1 - i] = y[i] - '0';// 2. 模擬加法的過程add(c, a, b); // c = a + b// 輸出結果for (int i = lc - 1; i >= 0; i--) cout << c[i];return 0;
}