高精度减法

一、算法描述

要实现两个高精度数的减法,和高精度加法一样都是模拟竖式计算的过程,主要就是解决以下两个问题。

谁大谁小?

由于这两个数字都很大,但是不知道谁更大,所以要先判断哪个数更大,思路如下:

  • 判断这两个数谁的位数更大,位数更大的自然更大。

  • 如果位数不相同,从最高位开始往低位遍历,判断两个数字是否相等,更大的那个原本的数字也更大。

  • 如果都一样,即默认是前面一个数更大,并不影响后面的操作。

代码如下:

bool cmp(vector<int> &A, vector<int> &B)
{
    if (A.size() != B.size())   return A.size() > B.size();
    else
        for (int i = A.size() - 1; i >= 0; --i)
            if (A[i] != B[i])
                return A[i] > B[i];
    return true;
}

如何计算?

解决了正负问题,现在来解决如何实现大数减小数。

  • 这依然是一个模拟问题,思考如何列竖式计算两个数的减法。

  • 从小到大遍历第一个数(第一个数不小),t += A[i],如果第二个数在当前位数还有数,减去该数,t -= B[i],还有别忘了处理前一位计算可能产生的借位。

  • 将计算结果加入到答案数组中,由于t有两种情况,t >= 0 || t < 0,所以可以统一处理:(t + 10) % 10

  • t < 0时,就是产生了借位,令t = -1,方便下一轮处理,否则令t = 0表示没有产生借位。

  • 最后还需要注意,如果两个数差距非常小,即最后的结果产生了很多前导 0 ,此时我们需要消除,因为输出的时候不需要这些前导 0

  • 但是也要注意如果两个数相等,那么最后的结果是 0 ,要保留最后一个 0

经过优化之后代码如下:

vector<int> sub(vector<int> &A, vector<int> &B)
{
    vector<int> C;
    int t = 0;
    
    for (int i = 0; i < A.size(); ++i)
    {
        t += A[i];
        if (i < B.size())   t -= B[i];
        
        C.push_back((t + 10) % 10);
        if (t < 0)  t = -1;
        else    t = 0;
    }
    while (C.size() > 1 && C.back() == 0)   C.pop_back();
    
    return C;
}

说明:

  • |A|+|B|可以转化为 A+BABBA(A+B) 这四种情况,都是可以用高精度加减法解决的,只需要特殊处理一下输入即可,所以当前讨论的都是正整数。

二、题目描述

给定两个正整数(不含前导 0 ),计算它们的差,计算结果可能为负数。

输入格式

共两行,每行包含一个整数。

输出格式

共一行,包含所求的差。

数据范围

1105

输入样例:

32
11 

输出样例:

21 

三、题目来源

AcWing算法基础课-792.高精度减法

四、源代码

#include <iostream>
#include <vector>

using namespace std;

const int N = 100010;

bool cmp(vector<int> &A, vector<int> &B)
{
    if (A.size() != B.size())   return A.size() > B.size();
    else
        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 t = 0;
    
    for (int i = 0; i < A.size(); ++i)
    {
        t += A[i];
        if (i < B.size())   t -= B[i];
        
        C.push_back((t + 10) % 10);
        if (t < 0)  t = -1;
        else    t = 0;
    }
    while (C.size() > 1 && 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
    {
        cout << "-";
        C = sub(B, A);
    }
    
    for (int i = C.size() - 1; i >= 0; --i) cout << C[i];
    
    return 0;
}
posted @   grave-master  阅读(78)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示