基础算法(6) —— 高精度减法模板

高精度减法模板及例题:

在这里插入图片描述
模板题:
给定两个正整数,计算它们的差,计算结果可能为负数。

输入格式
共两行,每行包含一个整数。

输出格式
共一行,包含所求的差。

数据范围
1 1≤ 整数长度 1 0 5 ≤10^5
输入样例:

32
11

输出样例:

21

高精度减法步骤:

  1. 用字符串储存输入数据

  2. 将字符串转化成 vector数组(逆序)

  3. 比较A,B的大小

  4. 判断是否有 A B A≥B 的方法是:

    ·判断A的位数与B的位数是否不相同:
       不相同则返回A.size()>B.size() 即如果A.size() > B.size()成立则返回true,反之返回false
    ·判断A的位数与B的位数是否相同:
       如果相同,那么从高位开始比较,找到第一个不同的数字,哪个数字大,则对应的数大。
       此时返回A[i] > B[i] ,如果A[i] > B[i]则返回true,否则返回false;
    ·如果上述条件均满足,且未有返回值,则返回true 此时A==B
    
  5. 用sub()函数来执行高精度减法(t为借位)

  6. 此前已经默认了 A B A ≥ B ,则不需要再判断 i < B . s i z e ( ) i < B.size() 的情况

    ·求出当前的值主公式为 (当前的值)t=A[i]-B[i]-t。
       但是,由于A.size()≥B.size(),那么存在B[i]可能不存在的情况,
       所以是通过判断i<B.size()判断B[i]是否存在。
       如果存在,则要减去。
    ·当前的值t,如果结果是t<0,则需要借位,结果是t+10;
       当前的值t,如果结果是t>0,则不需要借位,结果仍然是t。
       综合一起判断则为:当前这一位的结果是((t+10)%10)
    ·如果t<0,则已经借位,已经借位的下一位要减去,则令t=1;如果t≥0,则t=0;
    
  7. 删除前导0的情况,假设如果是 10-10,如果不删除前导0,结果为00,所以要删除前导0。这里通过一个STL ---- pop.back()函数(详情看代码)

  8. 最后输出分两种情况如果 A B A≥B ,则 A B A-B ;如果 A < B A<B ,则 ( B A ) -( B - A)

  9. 逆序输出

#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
using namespace std;

//判断是否有A>=B
bool cmp(vector<int> &A,vector<int> &B)
{
    //判断A的位数与B的位数大小
    if(A.size() != B.size())//如果两个长度不相同,那么返回A.size() > B.size(),如果A.size() > B.size()成立则返回true,反之返回false
        return A.size() > B.size();
    //如果A和B的位数相同,那么从高位开始比较,找到第一个不同的数字,哪个数字大,则哪个数大。
    for(int i = A.size() - 1;i >= 0;i--)
    {
        if(A[i]!=B[i])
            return A[i] > B[i];
    }
    //此时A == B
    return true;
}
//C = A - B
vector<int> sub(vector<int> &A,vector<int> &B)
{
    vector<int> C;
    int t = 0;
    //已经保证A >= B,所以这里不需要再判断i < B.size()
    for(int i = 0;i < A.size();i++)
    {
        t = A[i] - t;//当前的值 = A[i] - 借位的t - B[i](如果B[i]存在的话)
        if(i < B.size())//如果B[i]存在
            t -= B[i];//则要减去B[i]
            
        //如果t≥0,就是t本身,如果t<0,那么就是t + 10,综合起来就是((t + 10) % 10):当前这一位
        C.push_back((t + 10) % 10);
        
        //如果t<0,就是已经借位;
        if(t < 0)
            t = 1;
        else
            t = 0;
    }
    //删除前导0的情况
    while(C.size() > 1 && C.back() == 0)
        C.pop_back();
    return C;
}
int main()
{
    string a, b;//字符串储存
    vector<int> A, B;
    cin >> 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');
    
    if(cmp(A,B))
    {
        vector<int> C = sub(A, B);
        for(int i = C.size() - 1;i >= 0;i--)
            printf("%d", C[i]);
    }
    //结果为负数的时候
    else
    {
        vector<int> C = sub(B, A);
        printf("-");
        for(int i = C.size() - 1;i >= 0;i--)
            printf("%d", C[i]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_46272108/article/details/108026986