算法基础一高精度

一般四类:大整数加法,减法,大整数乘小整数,大整数除以小整数

把大整数的每一位存到数组里面,因为int 和long long都存不下,存的时候大整数从后往前存,例如:大整数123456789,那么存的时候把9存到数组下标为0的地方,8存到数组下标为1的地方,其他依次,因为涉及到进位,最后输出的时候反过来输出就好了,数组用的vector。

一.大整数加法:

  加法注意进位,将数字以字符串形式输入,然后再一个一个逆序放到vector里面,注意数字字符要变成整数(即减去'0'),可以自己在纸上模拟一下。

下边即实现A+B:

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

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++)
    {
        if(i<A.size()) t+=A[i];
        if(i<B.size()) t+=B[i];
        C.push_back(t%10);这里可以写个加法式子来看一下,会比较好理解
        t/=10;//比如说上边计算出两个数之和小于10,那么进位为零,大于10,进位为1
    }
    if(t) C.push_back(1);//全部都加完了,还有一个进位,那么就要在最高位上补1
    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');
    
    auto C=add(A,B);//auto就是让编译器自己判断变量类型,这里等价于vector<int>C=add(A,B);
    
    for(int i=C.size()-1;i>=0;i--) printf("%d",C[i]);//记得逆序输出
    return 0;
}

 

二.大整数减法:

  感觉减法明显比加法复杂啊啊啊啊,需要借位,还要令判两数大小,首先和加法一样先输入,存入vector,用bool函数判断A是不是比B大。

下边即实现A-B:

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

bool cmp(vector<int>&A,vector<int>&B)
{
    if(A.size()!=B.size()) return A.size()>B.size();
    else
    {
        for(int i=A.size();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;
    for(int i=0,t=0;i<A.size();i++)//t作为那个借位,刚开始时没有借位则t=0
    {
        t=A[i]-t;
        if(i<B.size()) t-=B[i];//如果i比B的长度还大,B后边没数了,就是0,再减就没啥意义了那就不用减了
        C.push_back((t+10)%10);//因为分为两种情况t>0和t<0,在这里的话(t+10)%10在t>0时还是t,在t<0时他要问别人借,由于他借来了一位,那么他就要加10.
        if(t<0) t=1;
        else t=0;
    }
    while(C.size()>1&&C.back()==0) C.pop_back();//去掉前导0,比方说123-120,结果应该为3,但是不去前导0的话就会输出003
    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');
    
    if(cmp(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;
}

 

三.大整数乘一个小整数:

这个和加法有一点点类似,只是进位不只是1或者0.

下边即实现A*b:

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

vector<int> mul(vector<int>&A,int b)
{
    vector<int>C;
    
    int t=0;//t是进位
    for(int i=0;i<A.size()||t;i++)
    {
        if(i<A.size()) t+=A[i]*b;//这里注意判断一下这个i是不是小于那个数组A的长度,超过了还加,那么加的就会是奇奇怪怪的东西
        C.push_back(t%10);
        t/=10;
    }
   
    return C;
}

int main()
{
    string a;
    int b;
    cin>>a>>b;
    
    vector<int>A,C;
    for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0');//数字字符串逆序保存在A中,注意A中下标都是从0开始,到A.size()-1的;
    
    if(b) C=mul(A,b);//特判一下,如果b不为0进行乘法
    else C.push_back(0);//否则b等于0了,就只需要结果是一个0
    
    for(int i=C.size()-1;i>=0;i--) printf("%d",C[i]);
    return 0;
}

 

四.大整数除以小整数:

感觉除法也会有些复杂,但是代码短呀呼呼呼,主要得拿纸上手模拟

下边即实现A除以b

#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--)//只有除法的时候是按照A中倒着来的,因为在纸上算的时候就是从前往后走
    {
        r=r*10+A[i];//在纸上算的时候拿下来一位,可以模拟一下
        C.push_back(r/b);
        r%=b;
    }
    reverse(C.begin(),C.end());//需要翻转一下,不然没有办法去掉前导零,而且最后输出的时候是倒着输出的
    while(C.size()>1&&C.back()==0) C.pop_back();//去前导零
    return C;
}
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');
    
    int r=0;
    auto C=div(A,b,r);//r是余数
    for(int i=C.size()-1;i>=0;i--) printf("%d",C[i]);
    cout<<endl<<r<<endl;
    return 0;
}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值