大整数加法——求两个不超过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表示默认有前导0
	scanf("%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函数里,检查代码的时候就会头皮发麻。如果把每个函数的功能都分出来,整体上就会很整洁,也方便阅读检查代码。

  • 18
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值