算法基础题6:高精度

在这里插入图片描述
大写字母表示大整数,小写字母表示小整数。len(A)表示位数。
大整数一般存到数组中,从后往前依次存入数组。例如:
在这里插入图片描述
原因是当我们需要进位时比较方便,只需要在数组最后添加一个数即可。

例一:高精度加法
在这里插入图片描述
算法思路:
在这里插入图片描述
每一次都是:A+B+进位(0或1),若A或B不存在则为0。
代码如下:

#include<iostream>
#include<vector>
using namespace std;

const int N = 1000010;
vector<int> add(vector<int> &A,vector<int> &B)
{
    vector<int> C;
    int t = 0;//记录每次的进位
    for(int i = 0;i < A.size()||i < B.size();i++)
    {   //加上 A 的第 i 位上的数字(如果有的话)
        if(i < A.size()) t += A[i];
        //加上B的第i位上的数字(如果有的话)
        if(i < B.size()) t += B[i];
        //将每次的相加结果加入到C中
        C.push_back(t%10);
        t = t/10;
    }
    //若最后一次的进位位1,则加入到C中
    if(t) C.push_back(1);
    return C;
}
int main()
{
    string a,b;
    vector<int> A,B;
    cin >> a >> b;
    //将a倒序加入到A中
    for(int i = a.size() - 1;i >= 0;i--) A.push_back(a[i] - '0');
    //将b 倒序加入到B中
    for(int i = b.size() - 1;i >= 0;i--) B.push_back(b[i] - '0');
    auto C = add(A,B);//auto可以自动判断数据类型
    for(int i = C.size() - 1;i >= 0;i--) printf("%d",C[i]);
    return 0;
}

例二:高精度减法
在这里插入图片描述
算法思路:
在这里插入图片描述
首先,判断A和B谁大,若A大则计算A-B,若B大,则计算-(B-A)。然后,判断Ai-Bi-t是否大于0,若大于等于0说明没有借位,直接将Ai-Bi-t加入到容器,若小于0,则说明有借位,这时将Ai-Bi+10-t加入到容器中。最后别忘了去掉前导0,比如:结果为003,则需去掉前面的两个0。
代码如下:

#include<iostream>
#include<vector>
using namespace std;

//判断A是否>=B
bool cmpare(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];
        }
    }
    //A=B
    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] -t;
        //若B的第i个位置存在
        if(i < B.size()) t -= B[i];
        //若t>=0,则结果为t本身,若t<0,则结果为向高位借一位之后的数
        C.push_back((t+10)%10);
        if(t>=0){
            //若t>=0说明没有借位
            t = 0;
        }else{
            //若t<0说明借位了
            t = 1;
        }
    }
    //去掉前导0(比如:132-121=011)
    while(C.size() > 1&&C.back()==0) 
    {
        C.pop_back();
    }
    return C;
}
int main()
{
    vector<int> A,B;
    string 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(cmpare(A,B))
    {
        auto C = sub(A,B);
        for(int i = C.size() - 1;i >= 0;i--) printf("%d",C[i]);
    }else{
        auto C = sub(B,A);
        printf("-");
        for(int i = C.size() - 1;i >= 0;i--) printf("%d",C[i]);
    }
    return 0;
}

例三:高精度乘法
在这里插入图片描述
算法思路:大整数A和小整数b相乘,将b看成一个整体与A的每一位相乘。每次的结果为:(A0b+t0)%10,其中t0为上一步的进位,t1 = (A0b+t0)/10。注意:①要保证最后一步的进位加入到结果C中,需要在for循环中加一个条件,即t!=0时也要循环。②若结果全为0,需要去掉多余的前导0;
代码实现:

#include<iostream>
#include<vector>
using namespace std;

vector<int> mul(vector<int> &A,int b)
{
    vector<int> C;
    int t = 0;
    //i < A.size()||t的作用是乘到最后一位时若有进位时,即t!=0,将进位加入到C中。
    for(int i = 0;i < A.size()||t;i++)
    {
        if(i < A.size()) t += A[i]*b;
        C.push_back(t%10);
        t = t/10;
    }
    //去掉前导0
    while(C.size() > 1&&C.back()==0)
    {
        C.pop_back();
    }
    return C;
}
int main()
{
    string a;
    int b;
    vector<int> A;
    cin >> a >> b;
    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--) printf("%d",C[i]);
    return 0;
}

例四:高精度除法
在这里插入图片描述
算法思路:
在这里插入图片描述
大整数A和小整数b相除,r为每一步的余数,C为每一步的结果。
代码如下:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
//注意r是引用,可以返回r在函数中的值
vector<int> div(vector<int> &A,int b,int &r)
{
    vector<int> C;
    r = 0;//余数
    for(int i = A.size() - 1;i >= 0;i--)
    {
        r = r*10 + A[i];
        //注意不要写成r / 10
        C.push_back(r/b);
        r = r%b;
    }
    //C要翻转一下,使用还函数必须加#include<algorithm>
    reverse(C.begin(),C.end());
    //去掉前导0
    while(C.size() > 1&&C.back() == 0)
    {
        C.pop_back();
    }
    return C;
}
int main()
{
    vector<int> A;
    int b;
    string a;
    cin >> a >>b;
    for(int i = a.size() - 1;i >= 0;i--) A.push_back(a[i] - '0');
    int r;
    auto C = div(A,b,r);
    for(int i = C.size() - 1;i >= 0;i--) printf("%d",C[i]);
    cout << endl << r << endl;
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值