1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 大整数加法——求两个不超过200位的非负整数的和

大整数加法——求两个不超过200位的非负整数的和

时间:2022-08-26 22:59:29

相关推荐

大整数加法——求两个不超过200位的非负整数的和

10:大整数加法

描述

求两个不超过200位的非负整数的和。

输入

有两行,每行是一个不超过200位的非负整数,可能有多余的前导0。

输出

一行,即相加后的结果。结果里不能有多余的前导0,即如果结果是342,那么就不能输出为0342。

样例输入

22222222222222222222

33333333333333333333

样例输出

55555555555555555555

代码如下

#include<stdio.h>#include<string.h>void reverse(char str[],int n);//字符串反转函数void change(char str[],int n);//字符转数字函数int main(){char a[200]={0},b[200]={0};int r[201]={0};int n1,n2,i,max,f=0,k=0;//f用来判断相加结果有无前导0,赋值0表示默认有前导0scanf("%s",a);scanf("%s",b);n1=strlen(a);n2=strlen(b);reverse(a,n1);reverse(b,n2);change(a,n1);change(b,n2);max=(n1>n2)?n1:n2;for(i=0;i<max;i++)//求和过程{r[i]=(a[i]+b[i]+k)%10;k=(a[i]+b[i]+k)/10;//k表示每位数字求和产生的进位}r[i]=k;//要注意可能有最高位进位for(;i>=0;i--){if(f==0&&r[i]==0) continue;//判断结果有无前导0,有则跳过else f=1;//当f为1之后,遇到0就不会再跳过了printf("%d",r[i]);}if(f==0) printf("0");//如果结果就为0(即f的值未修改仍为0),那么输出0,}void reverse(char str[],int n){int i,t;for(i=0;i<n/2;i++){t=str[i];str[i]=str[n-i-1];str[n-i-1]=t;}}void change(char str[],int n){int i;for(i=0;i<n;i++) str[i]-=48;}

这道题做了蛮久,前前后后调试了很久。不过现在回想起来,其实很简单,关键仍是代码的思想。首先对于这类超长正数的加法,在我们人类计算看来与简单的加法其实本质是一样的,就是从个位开始,逐个位顺序相加,满十就进位。而题目为了干扰我们,输入的数据有些有前导0,但明白了计算过程就很简单。首先肯定是让两个数字都从最后一位开始计算,但是如果直接就这么处理,代码就会很复杂,至少看起来就会很头疼。

所以第一步的想法就是先把两个数字的高低位顺序调换,让低位在数组的前面,高位在后面。要注意这行代码for(i=0;i<n/2;i++)i<n/2,循环次数是数组个数一半,因为每次交换是将数组中的两个元素进行位置交换。(对于奇数个元素的数组就是最中间元素不交换,其他元素进行交换)

然后就是两个数组从[0]开始按顺序相加就行。

接下来就是要思考如何相加,因为数组里存的是字符,而不是整数,所以在做加法时就不能想当然的按整数进行加法运算。这里我就先想到把字符转换成数字,也就是void change(char str[],int n);函数的作用。每个元素减去0的ASCII码值(即48)就可以转换成数字。

最后一些步骤就看上面的代码就行了。

在这里我得到教训就是模块化编程的重要性,如果把所有代码都写在main函数里,检查代码的时候就会头皮发麻。如果把每个函数的功能都分出来,整体上就会很整洁,也方便阅读检查代码。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。