高精度算法

1. 高精度加法

给定两个正整数(不含前导 00),计算它们的和。

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

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

数据范围
1≤整数长度≤1000001≤整数长度≤100000
输入样例:
12
23
输出样例:
35

一开始的代码:

//高精度加法 
#include<iostream>
#include<string>
using namespace std;
int main()
{
	string a,b;
	int res[100010]={0},t;
	cin>>a>>b;
	int la=a.length(),lb=b.length(),i,j,l=max(la,lb);
	for(i=la-1,j=lb-1;i>=0&&j>=0;i--,j--)
	{
		res[l]+=(a[i]+b[j]-'0'-'0');
		t=res[l];
		res[l]=t%10;
		res[l-1]=t/10;
		l--;
	}//两个都有的加完了
	if(i>=0)
	{
		for(;i>=0;i--)
		{
			res[l]+=a[i]-'0';
			t=res[l];//不可以直接操作 
			res[l]=t%10;
			res[l-1]=t/10;
			l--;
		 } 
	 } 
	 else if(j>=0)
	 {
	 	for(;j>=0;j--)
		{
			res[l]+=(b[j]-'0')%10;
			t=res[l];
			res[l]=t%10;
			res[l-1]=t/10;
			l--;
		 } 
	 	/*
	 	while(1)
	 	{
	 		res[l]+=(b[i]-'0')%10;
			res[l-1]=(b[i]-'0')/10;
			l--;j--;
			if(j<0)break;
			//不可以在while循环里面i--
			//因为在下面的操作里i会少1,下标就错了 
		 }
		 */
	 }
	 for(i=0;;i++)
	 if(res[i]!=0)
	 break;
	 for(;i<=max(la,lb);i++)
	 cout<<res[i];
} 

代码的优化: 

#include<iostream>
#include<vector>//为了方便计算大小
using namespace std;
vector<int>add(vector<int>a,vector<int>b)
{
    int t=0;//余数
    vector<int>c;
    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=t/10;
    }
    if(t)c.push_back(1);
    return c;
}
int main()
{
    string a,b;
    vector<int>A,B;
    cin>>a>>b;
    for(int i=a.length()-1;i>=0;i--)
    {
        A.push_back(a[i]-'0');
    }
    for(int j=b.length()-1;j>=0;j--)
    {
        B.push_back(b[j]-'0');
    }
    auto c=add(A,B);
    for(int i=c.size()-1;i>=0;i--)
    cout<<c[i];
    return 0;
}

主要是考虑到每一位都是:两位待加数加上进位。

所以可以变成,只有有一位存在就进行循环,当哪个数组没有遍历完再加上那个数组的值,t再进行%10就是这一位的结果,除10是进位

最后在跳出循环后判断t当t不为0那么最高位是1即可

2.高精度减法

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

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

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

数据范围
1≤整数长度≤10的5次方
输入样例:
32
11
输出样例:
21

#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
const int N=1e6+10;
vector<int>jf(vector<int>a,vector<int>b)
{
    vector<int>c;
    for(int i=0;i<a.size();i++)
    {
        int t;
        if(i<b.size())
        t=a[i]-b[i];
        else
        t=a[i];
        if(t<0)
        {
            t=10+t;
            a[i+1]--; 
            c.push_back(t);
        }
        else
        c.push_back(t);
    }
    return c;
}
int cmp(vector<int>a,vector<int>b)
{
    if(a.size()>b.size())
    return 1;
    else if(a.size()==b.size())
    {
        for(int i=a.size()-1;i>=0;i--)//由最高位决定 
        {
            if(a[i]-b[i]>0)
            return 1;
            else if(a[i]-b[i]<0)
            return -1;
        }
    }
    else
    return -1;
    return 0;
}
int main()
{
    char a[N],b[N];
    int flag=0;
    vector<int>A,B;
    cin.getline(a,N);
    cin.getline(b,N);
    for(int i=strlen(a)-1;i>=0;i--)
    {
        A.push_back(a[i]-'0');
    }
    for(int i=strlen(b)-1;i>=0;i--)
    {
        B.push_back(b[i]-'0');
    }
    vector<int>res;
    if(cmp(A,B)<0)
    {
        flag=1;
        cout<<"-";
        res=jf(B,A);
    }
    else if(cmp(A,B)==0)
    cout<<'0';
    else
    {
        flag=1;
        res=jf(A,B);
    }
    if(flag)
    {
    	int i;
        for(i=res.size()-1;i>=0;i--)
        if(res[i]!=0)
        break;
        for(;i>=0;i--)
        cout<<res[i];
    }
    return 0;
}

注意:

这个题,为了方便,进行了一次大小的比较,即保证进行减法的时候A>=B。

并且减法需要考虑到前导零,即230-229答案是1,但是我的答案是001所以需要考虑清楚

3.高精度乘法

给定两个非负整数(不含前导 00) AA 和 BB,请你计算 A×BA×B 的值。

输入格式

共两行,第一行包含整数 AA,第二行包含整数 BB。

输出格式

共一行,包含 A×BA×B 的值。

数据范围

1≤A的长度≤100000
0≤B≤10000

输入样例:
2
3
输出样例:
6

 代码实现:

#include<iostream>
#include<vector>
using namespace std;
vector<int>cf(vector<int>a,int b)
{
    vector<int>res;
    int t=0;
    for(int i=0;i<a.size();i++)
    {
        t+=a[i]*b;
        res.push_back(t%10);
        t=t/10;
    }
    if(t)
    res.push_back(t);
    while(res.size()>1&&res.back()==0)res.pop_back();
    return res;
}
int main()
{
    string a;
    int b;
    cin>>a>>b;
    vector<int>A;
    for(int i=a.length()-1;i>=0;i--)
    {
        A.push_back(a[i]-'0');
    }
    auto res=cf(A,b);
    for(int i=res.size()-1;i>=0;i--)
    {
        cout<<res[i];
    }
    return 0;
}

注意点:

1.因为其中有一个数更小,所以,那个数就是当整数进行读入。而另一个写成vector<int>数组的形式

2.对乘法本质的理解,较小的那个数b乘以数组的各个位,其中这一位答案是b*a[i]%10+t

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值