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

C++題解 高精度除法

C++題解 高精度除法

題目描述

輸入格式

共兩行,第一行包含整數 AA,第二行包含整數 BB。

輸出格式

共兩行,第一行輸出所求的商,第二行輸出所求餘數。

資料範圍

$$
1≤A的長度≤100000,\
1≤B≤10000,\
B 一定不為 0
$$

輸入樣例:

7
2

輸出樣例:

3
1

思路

對於該題目的實現,我們使用一個數組進行除法的模擬,為了方便此處使用vector。

資料的輸入

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

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

模擬除法

在這裡,我們使用一個整型變數 r 進行運算的儲存。根據我們人類的手算方法,我們對最高位進行除法後,得到餘數 r

,此時我們會將被除數的下一位數拉下來補上再進行運算,這個過程可以被描述為 r * 10 + a[i] ,一開始我們將r置為0。

最後,最低位除法完成後,判斷最高位是否存在 前導0 ,若是則進行相應處理。

資料的輸出

為了和四則高精度運算統一,在陣列中,商的儲存是從0開始由高向低的,所以我們使用一個 reverse函式將其反轉。

前導0處理

這裡有一個比較特殊的情況,80/9如果我們得到了 08 ,那麼我們輸出的時候就會導致我們出錯。這裡我們做了處理,迴圈檢測高位數字,有0則去除,直到高位數字不為0。

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

vector<int> div(vector<int>& A, int b, int& r)
{
    vector<int> C;

    for (int i = A.size() - 1; i >= 0 ; -- i) {
        r = r * 10 + A[i];
        C.push_back(r / b);
        r %= b;
    }

    reverse(C.begin(), C.end());

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

    return C;
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    string a; int b;
    cin >> a >> b;

    vector<int> A;

    for(int i = a.size() - 1; i >= 0; i --)
        A.push_back(a[i] - '0');

    int r = 0;
    auto C = div(A, b, r);

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

    return 0;
}