1. 程式人生 > 其它 >C++題解 高精度減法

C++題解 高精度減法

C++題解 高精度減法

題目描述

給定兩個正整數(不含前導 00),計算它們的差,計算結果可能為負數。

輸入格式

共兩行,每行包含一個整數。

輸出格式

共一行,包含所求的差。

資料範圍

$$
1≤整數長度≤10^5
$$

輸入樣例:

32
11

輸出樣例:

21

思路

對於該題目的實現,我們使用兩個陣列進行加法的模擬,為了方便此處使用vector。

資料的輸入

可以看到數字的長度遠遠超過了long long的需要,我們需要使用字串進行資料的讀入。

注意,為了運算方便,應該從字串的末尾將原數字倒序的進行讀入,想一想為什麼。

模擬減法

負數情況的處理

首先我們需要回想一下,對於一個減法 3 - 5 = -2

,我們人類一般會轉換為 - (5 - 3) = -2 進行計算,那麼對於程式也應該使用這種思想。定義一個cmp函式,獲取兩個數字的長度,當長度相同時,我們從最高位向最低位逐位比較,從而判斷出兩個數的大小。

借位思想

在這裡,我們使用一個整型變數 r 進行運算的儲存。將數字 a b 的相應位相減後,我們通過儲存 (r + 10) % 10 作為該位的最終結果,隨後若 r < 0 ,令 r = 1 作為下一位運算中現在位的借位。

關於 (r + 10) % 10
$$
F (r) = \begin{Bmatrix} r &, r\ge0,\\ r + 10 &, r < 0 \end{Bmatrix}
$$

對於借位 r

,應該有這兩種情況,但是我們使用 (r + 10) % 10 可以合二為一,想想為什麼。

資料的輸出

按照人類的習慣,我們將陣列從最高位開始輸出即可。

前導0處理

這裡有一個比較特殊的情況,例如 222 - 221 我們得到的其實是 002 ,那麼我們輸出的時候就會導致我們出錯。這裡我們做了處理,迴圈檢測高位數字,有0則去除,直到高位數字不為0。

以下是程式碼實現

//
// Created by Owwkmidream on 2021/10/30.
//
#include "iostream"
#include "vector"
using namespace std;

bool cmp(vector<int>& A, vector<int>& B)
{
if(A.size() != B.size()) return A.size() > B.size();

for(int i = A.size() - 1; i >= 0; i --)
if(A[i] != B[i])
return A[i] > B[i];

return true;
}

vector<int> sub(vector<int>& A, vector<int>& B)
{
vector<int> C;

int r = 0;
for(int i = 0; i < A.size(); i ++) {
r = A[i] - r;
if(i < B.size()) r -= B[i];
C.push_back((r + 10) % 10);
if(r < 0) r = 1;
else r = 0;
}

while (C.size() > 1 and C.back() == 0) C.pop_back();

return C;
}

int main() {
string a, b;
cin >> a >> b;

vector<int> A, B;
for(int i = a.size() - 1; i >= 0; i --) A.push_back(a[i] - '0');
for(int i = b.size() - 1; i >= 0; i --) B.push_back(b[i] - '0');

vector<int> C;
if(cmp(A, B))
C = sub(A, B);
else
C = sub(B, A), cout << "-";

for(int i = C.size() - 1; i >= 0; i --) cout << C[i];

return 0;
}