大数加法

思路:

把两个加数各个数位上的数字相加,把相加结果的个位数字储存到第三个变量中去,而把十位数字提取出来参与下一次加法运算。
12345
+1247
用上图表示即先做 5+7=12,把12 的2放到一个第三个变量中,然后十位数字(进位)1则暂时储存起来,当做4+4=8的时候再把1加进来即=9。不断循环之后可得到两个大数相加的结果。

程序的实现:

考虑到是意两个长正整数,所以选用字符串数组来储存长整数。首先建立一个整形n 用来存放两加数中位数较多的那个加数的位数。之后再建立一个字符串指针用来存放结果char *str3 = (char*)malloc(sizeof(char)*(n+2));
大小为n+2表示多申请两个字符,一个是结束符'\0',一个是放到第一个字符,存放进位,当两个数最高位相加后,如果有进位,保存到这里 如99+99=198,那么进位的1需要多用一位来存放。


转置的思路:

加法函数前面的void reverse(char str[])函数。因用加法函数做主来的结果正好与实际结果相反(即首位调换了一下),故用一个转置函数把顺序换回来。实现过程比较简单,如一串字符串为1234567,长度为7。那么从第1个数开始到第3个,依次与它们所对应的那个数做调换,即1与7交换,2与6交换,3与5交换。3次交换结束后即为7654321。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define STRLENTH 100
/*数组转置*/
void reverse(char str[])
{
	int left = 0;//第一个元素
	int right = strlen(str)-1;//最后一个元素
	char temp;
	while(left < right)
	{
		temp = str[left];
		str[left] = str[right];
		str[right] = temp;
		left++;
		right--;
	}
}
char* big_num_add(char str1[],char str2[])
{
	int n1 = strlen(str1);	//求第一个加数的位数
	int n2 = strlen(str2);	//求第二个加数的位数
	int n = n1>n2 ? n1:n2;	//求两个加数中最大的位数
	int i = 0;
	int flag = 0;			//进位值,个位相加时,没有进位
	char sum ;				//每一位相加的和
	char *str3;				//存放和

/*存放加数的和,两个加数的最大位+两位,存放('\0'(reverse函数用到,strlen)及最高位有可能产生的进位)*/
	str3 = (char*)malloc(sizeof(char)*(n+2));

	n1--;//指向最低位的下标(从个位开始计算)
	n2--;
	while(n1 >= 0 && n2 >= 0)
	{
		/*求每一位上的和:本位和 + 进位*/
		sum = str1[n1] + str2[n2] + flag - '0';
		/*有进位*/
		if(sum > '9')
		{
			str3[i] = sum - 10;	//去掉进位后存于数组中
			flag = 1;			//有进位,加法进位只能是1
		}
		/*无进位*/
		else
		{
			str3[i] = sum;
			flag = 0;
		}
		/*为下一位做准备*/
		n1--;
		n2--;
		i++;
	}
	/*处理位数高的剩余位*/

	if(n1 > n2)//第一位没有处理完
	{
	//	for(;n1>=0;n1--)
		while(n1 >= 0)
		{
			sum = str1[n1] + flag ;//上一位的进位
			if(sum > '9')
			{
				str3[i] = sum - 10;	//去掉进位后存于数组中
				flag = 1;			//有进位,加法进位只能是1
			}
			else
			{
				str3[i] = sum;
				flag = 0;
			}
			n1--;
			i++;
		}
	}
	if(n2 > n1)//第二个加数,没有处理完
	{
		while(n2 >= 0)
		{
			sum = str2[n2] + flag ;//上一位的进位
			if(sum > '9')
			{
				str3[i] = sum - 10;	//去掉进位后存于数组中
				flag = 1;			//有进位,加法进位只能是1
			}
			else
			{
				str3[i] = sum;
				flag = 0;
			}
			n2--;
			i++;
		}
	}
	/*加完之后看看是否有进位:99+999,加完之后仍有进位*/
	if(flag == 1)
	{
		str3[i] = '1';
		i++;
		str3[i] = '\0';
	}
	else
		str3[i] = '\0';//和数组最后赋值'\0'
/*上述操作执行完后,低位存到了前面,高位存在了后面,所以得转置过来*/
	reverse(str3);
	return str3;	
}

int main()
{
	char add1[STRLENTH];
	char add2[STRLENTH];
	printf("请输入两个加数:(以回车键作为分隔符)\n");
	gets(add1);
	gets(add2);
	printf("the sum is:%s\n",big_num_add(add1,add2));
	return 0;
}


大数加法_第1张图片


你可能感兴趣的:(大数加法)