高精度的得来在于竖式计算,这就是高精度的原理
导入
许多年以前,我学了Python语言,在Python语言中,高精度是不可能出现的,这是因为他本来就是用高精度计算的,但我相信众多同学都没有学过这语言(这什么语言,真的有这么实用?),C++中,因为要搞竞赛,也就没有好心人来帮帮孩子了,于是,我们进入到第一个高精度算法——加法
题目
输入格式给出两个整数a,b,求他们的和。
a,b的位数不超过300位。
输出格式第一行一个整数a
第二行一个整数b
输入输出样例 输入输出只有一行,为两个整数的和。
输出101000000000000
203000000000000
304000000000000
乍一看题目,同学就敲出了一下代码:
python:
a = int(input()) b = int(input()) print(a+b)
C++(不要复制!不要复制!!不要复制!!!):
#includeusing namespace std; int main(){ long long int a,b; cin>>a>>b; cout<
两种不一样的语言,运行的结果也不一样,Python这样交就Accept了,而C++这样交就会Wrong Answer或者Runtime Error,C++人表示,为什么差不多的代码Python就能对!而我不行!,不要说,上面有讲,所以这道题就需要高精度了~
高精度加法遵循一个规则,就是按照竖式进行计算,这好像说过了。
数位对齐是其中一个难点,其实这个很简单,也就相当于把数组倒过来,这样就行了
"可是怎么倒过来呀!而且输入问题呢?!"一个同学站了起来。
这就需要我们的字符串读入数字了,可以用gets()功能,也可以使用scanf()功能,还可以使用getline(),下面是代码
string a,b; gets(a); gets(b);
转换的问题可以用for循环来表示, x i = a a . s i z e ( ) − 1 − i − ′ 0 ′ x_i=a_{a.size()-1-i}-'0' xi=aa.size()−1−i−′0′,代码如下:
for(int i=a.size()-1;i>=0;i--) x[i]=a[a.size()-i-1]-'0'; for(int i=b.size()-1;i>=0;i--) y[i]=b[b.size()-i-1]-'0';
上面的代码x和y数组是
i
n
t
int
int类型,减’0’表示转换成数字,看下ASCAII码表,你可以理解一下:
从第一个for来吧,都同理
当 i i i为第 i i i个元素时(a=“12345”):
| i=0 | i=1 | i=2 | i=3 | i=4 | ||
|---|---|---|---|---|---|---|
| a | a 5 − 1 − 0 a_{5-1-0} a5−1−0=‘5’ | a 5 − 1 − 1 a_{5-1-1} a5−1−1=‘4’ | a 5 − 1 − 2 a_{5-1-2} a5−1−2=‘3’ | a 5 − 1 − 3 a_{5-1-3} a5−1−3=‘2’ | a 5 − 1 − 4 a_{5-1-4} a5−1−4=‘1’ | |
| x | x 0 x_0 x0=5 | x 1 x_1 x1=4 | x 2 x_2 x2=3 | x 3 x_3 x3=4 | x 4 x_4 x4=5 |
输出看看(真的倒过来了)~
for(int i=0;i下面是模拟竖式了!因为已经倒过来了,所以,我们的 0 < = i < = m a x ( l e n 1 , l e n 2 ) 0<=i<=max(len1,len2) 0<=i<=max(len1,len2),这里的 l e n 1 len1 len1表示x数组的长度,也可以理解为 a . s i z e ( ) a.size() a.size()因为都一样, l e n 2 len2 len2就是第二个了。两数进行相加,存在 z z z数组里( z z z数组尽量大,否则我们就
可以愉快地RE了),代码如下:for(int i=0;iz[i]=x[i]+y[i]; } “哈哈哈哈哈哈……”一个提高班的大佬笑,“这咋可能?”
当然不可能!如果这样就行了,我们还没考虑进位呢!可以用个t来存储 z i = x i + y i z_i=x_i+y_i zi=xi+yi的进位值,即 t = z i 整除 10 t=z_i 整除 10 t=zi整除10, z i z_i zi取个位,所以要 m o d 10 mod 10 mod10,代码如下:
for(int i=0;iz[i]=x[i]+y[i]; t=z[i]/10; z[i]%=10; } “这好像有问题呀!”
“对!要是这样交上去,肯定会WA的!因为还没加进位值~”
我们可以先把 t t t设为 0 0 0,再遍历for,代码如下:
int t=0,len1=a.size(),len2=b.size(),len3=len1>len2?len1:len2;//len3的值相当于max(len1,len2),本代码写的是三目运算符 for(int i=0;iz[i]=x[i]+y[i]+t; t=z[i]/10; z[i]%=10; } “输出问题呢?”
现在开始讲:因为是倒着进行加法,所以要反过来输出,代码如下:
for(int i=len3-1;i>=0;i--) cout<那所有代码如下:
#include#include #include using namespace std; int main(){ int x[305],y[305],z[305]; string a,b; cin>>a>>b; for(int i=a.size()-1;i>=0;i--) x[i]=a[a.size()-i-1]-'0'; for(int i=b.size()-1;i>=0;i--) y[i]=b[b.size()-i-1]-'0'; int t=0,len1=a.size(),len2=b.size(),len3=len1>len2?len1:len2; for(int i=0;i z[i]=x[i]+y[i]+t; t=z[i]/10; z[i]%=10; } for(int i=len3-1;i>=0;i--) cout< 如果你这样交上去,有可能会WA呀!因为在Linux系统下,变量没设初值会乱的,所以应该如下:
#include#include #include using namespace std; int x[305],y[305],z[305]; int main(){ string a,b; cin>>a>>b; for(int i=a.size()-1;i>=0;i--) x[i]=a[a.size()-i-1]-'0'; for(int i=b.size()-1;i>=0;i--) y[i]=b[b.size()-i-1]-'0'; int t=0,len1=a.size(),len2=b.size(),len3=len1>len2?len1:len2; for(int i=0;i z[i]=x[i]+y[i]+t; t=z[i]/10; z[i]%=10; } for(int i=len3-1;i>=0;i--) cout< “老师!这代码交上去还是会WA呀!”
这是因为最后加的有进位但没有输出!好了!我们判断一下t的值,如果大于0就输出,AC代码如下,重在理解:
#include#include #include using namespace std; int x[305],y[305],z[305]; int main(){ // char a[305],b[305]; string a,b; cin>>a>>b; for(int i=a.size()-1;i>=0;i--) x[i]=a[a.size()-i-1]-'0'; for(int i=b.size()-1;i>=0;i--) y[i]=b[b.size()-i-1]-'0'; // for(int i=0;i // cout< len2?len1:len2,len4=len1 z[i]=x[i]+y[i]+t; t=z[i]/10; z[i]%=10; } if(t!=0){cout< =0;i--) cout< 重在理解,如有不对请多多指教
Python一步到位:无换行输入:
print(sum(list(map(int,input().split(" ")))))有换行输入:
a = int(input()) b = int(input()) print(a+b)看到这了,还不能点赞+收藏吗



