【算法】高精度 +

问题引入

输入两个数a,b,输出a+b
其中 1 ≤ a , b ≤ 1 0 1000 1\le a,b \le 10^{1000} 1a,b101000
此时,正常的输入已近炸了,所以对于蒟蒻来说要使用高精度。

介绍

高精度算法(High Accuracy Algorithm)是处理大数字的数学计算方法。在一般的科学计算中,会经常算到小数点后几百位或者更多,当然也可能是几千亿几百亿的大数字。一般这类数字我们统称为高精度数,高精度算法是用计算机对于超大数据的一种模拟加,减,乘,除,乘方,阶乘,开方等运算。对于非常庞大的数字无法在计算机中正常存储,于是,将这个数字拆开,拆成一位一位的,或者是四位四位的存储到一个数组中, 用一个数组去表示一个数字,这样这个数字就被称为是高精度数。高精度算法就是能处理高精度数各种运算的算法,但又因其特殊性,故从普通数的算法中分离,自成一家。

原理

想一想,你是如何做加法的,如果让你做114514+1919810你是不是如下图做的:
在这里插入图片描述
我们从末位开始,每次相加,满十进一。
所以我们可以用数组来模拟这一个过程。

代码实现

转字符

由于输入的数太大了,我们用字符串输入,再把它转成数字存在数组中。

	string s,a,b;
	cin>>a>>b;
    const int N=1001;
    int na[N],nb[N],nc[N],lena=a.size(),lenb=b.size();
    fill(na,na+N,0);
	fill(nb,nb+N,0);
	fill(nc,nc+N,0);
    for(int i=lena-1;i>=0;i--) 
		na[lena-i]=a[i]-'0';
    for(int i=lenb-1;i>=0;i--) 
		nb[lenb-i]=b[i]-'0';

开始

由于我们是倒着存字符串的,所以我们现在可以直接从1开始相加,模拟原来的从末位开始相加。
e.g.

for(int i=1;i<=lenc;i++)
		nc[i]+=na[i]+nb[i],nc[i+1]+=nc[i]/10,nc[i]%=10;

解释:
na,nb为输入的字符串转成的数字,nc为答案数组。
同时,我们还要模拟进位,及:
n c [ i + 1 ] + = n c [ i ] / 10 , n c [ i ] − = 10 nc[i+1]+=nc[i]/10,nc[i]-=10 nc[i+1]+=nc[i]/10,nc[i]=10
注意,前提是 n c [ i ] ≥ 10 nc[i]\geq10 nc[i]10,所以这里推荐像上面那样打。

去前导0

单单运算完上面两步还是不够的,我们还要去前导0。
不去有惊喜
方法也很简单,碰到第一个非0数字就break。
同时,要判断答案为0的存在。

while(nc[lenc]==0&&lenc>1)
		lenc--;

例题

题目

输入两个数 a , b a,b a,b,输出 a + b a+b a+b
其中 1 ≤ a , b ≤ 1 0 1000 1\le a,b \le 10^{1000} 1a,b101000

输入格式

  • 第一行两个整数a和b

输出格式

  • 共一行,输出a+b

输入/输出例子
在这里插入图片描述

样例解释

Code

#include<bits/stdc++.h>
using namespace std;
string a,b;
string add(string a,string b)
{
	string s;
	cin>>a>>b;
    const int N=1001;
    int na[N],nb[N],nc[N],lena=a.size(),lenb=b.size();
    fill(na,na+N,0);
	fill(nb,nb+N,0);
	fill(nc,nc+N,0);
    for(int i=lena-1;i>=0;i--) 
		na[lena-i]=a[i]-'0';
    for(int i=lenb-1;i>=0;i--) 
		nb[lenb-i]=b[i]-'0';
	int lenc=max(lena,lenb)+10;
	for(int i=1;i<=lenc;i++)
		nc[i]+=na[i]+nb[i],nc[i+1]+=nc[i]/10,nc[i]%=10;
	while(nc[lenc]==0&&lenc>1)
		lenc--;
	for(int i=lenc;i>=1;i--)
		s+=nc[i]+'0';
	return s;
}
signed main()
{
	cin>>a>>b;
	cout<<add(a,b);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值