C++ 高精度四则运算(2) 乘除法

449 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情

前言 介绍了高精度四则运算的前两种加减法,今天介绍最后两种乘除法 依旧是采用AcWing y总算法基础课模板

3.高精度除法

1.模板介绍

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int>sub(vector<int>&A,int B,int &r)
{
    r=0;
    vector<int>C;
    for(int i=0;i<A.size();i++)
    {
        //r为余数,带入参数只是为了方便获取
        //前一位的余数*10+当前位数 为当前的被除数
        r=r*10+A[i];
        //r/B为商
        C.push_back(r/B);
        r%=B;
    }
    //逆序为了清除前置0
    reverse(C.begin(),C.end());
    while(C.size()>1&&C.back()==0)
    {
        C.pop_back();
    }
    //然后
    reverse(C.begin(),C.end());
    return C;
}

2.模板详解

1)参数确定

高精度乘法 限于A>=B,且B是一个较小的数(不是很小,只是满足c++可处理的数)

新增一个r参数,作为当前位除法的余数

注:余数参数可以省去,看题目所求的结果是否有余数,如果只求商,余数可以在里面进行定义,如果要求返回商和余数,就需要传入余数变量的地址,见练手例题

vector<int>sub(vector<int>&A,int B,int &r)

2)执行

    for(int i=0;i<A.size();i++)
    {
        //r为余数,带入参数只是为了方便获取
        //前一位的余数*10+当前位数 为当前的被除数
        r=r*10+A[i];
        //r/B为商
        C.push_back(r/B);
        r%=B;
    }

为了帮助读者理解r的作用,画了一个小图,鼠标画图望见谅🥲

只需要理解计算机做运算是逐位逐位进行运算,而不是我们人一看到11/2 直接商5了

3)完善

//如上图得到的结果是11/2=05...1
此时我们就需要进行去掉前置0,所以进行一个逆序
reverse(C.begin(),C.end());
while(C.size()>1&&C.back()==0)
{
    C.pop_back();
}
//去掉前置0后 不要忘记将结果转回来
reverse(C.begin(),C.end());
return C;

3.练手例题

794. 高精度除法 - AcWing题库

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int>sub(vector<int>&A,int B,int &r)
{
    .....
}
int main()
{
    string a;int b;
    cin>>a;
    vector<int>A;
    for(int i=0;i<a.size();i++)
    {
        A.push_back(a[i]-'0');
    }
    int r;
    cin>>b;
    auto C=sub(A,b,r);
    for(int i=0;i<C.size();i++)
    {
        cout<<C[i];
    }
    cout<<endl<<r;
}

4.高精度乘法

1.模板介绍

#include <iostream>
#include <vector>
#include <string>
using namespace std;
vector<int> A, B;
vector<int> mul(vector<int> &A,int B)
{
    int t = 0;
    vector<int> C;
    for(int i=0;i<A.size()||t;i++)
    {
        if(i<A.size())t+=A[i]*B;
        C.push_back(t%10);
        t/=10;
    }
    while(C.size()>1&&C.back()==0)
    {
        C.pop_back();
    }
    return C;
    
}

2.模板详解

1)参数确定

与除法一致

vector<int> mul(vector<int> &A,int B)

2)执行

乘法相较于前三种 还是较好理解 此处不对其展开讲解,如有问题可以留言

//这里for循环的中止条件还包括一个||t,还要考虑到最高位的进位问题,与加法的处理方式不同,直接在for循环进行添加。
加法是for循环接触后,判断进位是否存在
for(int i=0;i<A.size()||t;i++)
{
    if(i<A.size())t+=A[i]*B;
    C.push_back(t%10);
    t/=10;
}

3)完善

同样我们需要考虑到一个前置0的问题,解决方式与除法一致

while(C.size()>1&&C.back()==0)
{
    C.pop_back();
}
return C;

3.练手例题

793. 高精度乘法 - AcWing题库

#include <iostream>
#include <vector>
#include <string>
using namespace std;
vector<int> A, B;
vector<int> mul(vector<int> &A,int B)
{
...    
}
int main()
{
    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');
    }
        auto C = mul(A,b);
        for (int i = C.size() - 1; i >= 0; i--)
        {
            cout << C[i];
        }
}

每日更新自己的算法笔记,谢谢观看。