【51Nod】1005 大数加法

给出2个大整数A,B,计算A+B的结果。

Input

第1行:大数A 第2行:大数B (A,B的长度 <= 10000 需注意:A B有可能为负数)

Output

输出A + B

Input示例

68932147586 468711654886

Output示例

537643802472

====================================================================================================

问题解法分析:

因为长度小于10000 所以可以依据模拟进位的方法进行解决

解决思路如下:

1:比较两个字符串类型:

如果为如果同为正数(负数) 则进行直接相加(负数相加负号)

若为一正一负,则对负数取消负号进行正数与负数的相减

保证此时字符串已经不存在正负号问题

2:对字符串进行转换

比较两个字符串的长度,若长短不一样则对短的字符串进行补齐 保证两个字符串长短一样

转换函数如下:

 1 void Trans(char *str_num1, char *str_num2, char *tempbuf1, char *tempbuf2)
 2 {
 3     int len_num1=0;
 4     int len_num2=0;
 5     int i=0;
 6     while(str_num1[i]!=‘\0‘)
 7     {
 8         len_num1++;
 9         i++;
10     }
11 //    printf("字符串1的长度: length1=%d\n",len_num1);
12     i=0;
13     while(str_num2[i]!=‘\0‘)
14     {
15         len_num2++;
16         i++;
17     }
18 //    printf("字符串2的长度: length2=%d\n\n",len_num2);
19
20     tempbuf1[0]=‘0‘;
21     tempbuf2[0]=‘0‘;
22
23 //=======================================================================
24     if(len_num2>=len_num1)                                   //补成相同长度
25     {
26         for(i=1;i<=(len_num2-len_num1);i++)
27         {
28             tempbuf1[i]=‘0‘;
29         }
30         for(i=len_num2-len_num1+1;i<=len_num2;i++)
31         {
32             tempbuf1[i]=str_num1[i-(len_num2-len_num1+1)];
33         }
34         for(i=1;i<=len_num2;i++)
35         {
36             tempbuf2[i]=str_num2[i-1];
37         }
38     }
39 //------------------------------------------
40     else if(len_num2<len_num1)
41     {
42         for(i=1;i<=(len_num1-len_num2);i++)
43         {
44             tempbuf2[i]=‘0‘;
45         }
46         for(i=len_num1-len_num2+1;i<=len_num1;i++)
47         {
48             tempbuf2[i]=str_num2[i-(len_num1-len_num2+1)];
49         }
50         for(i=1;i<=len_num1;i++)
51         {
52             tempbuf1[i]=str_num1[i-1];
53         }
54     }
55
56 }

3:进行加减运算

对已经处理过的字符串进行加减计算

计算方式模仿竖式进位进行计算

加法算法:

 1     int i=0;
 2     int temp=0;
 3     int jinwei=0;
 4     int len=0;
 5     while(tempbuf1[i]!=‘\0‘)
 6     {
 7         len++;
 8         i++;
 9     }
10     for(i=len-1;i>=0;i--)
11     {
12         temp=(int)(tempbuf1[i]+tempbuf2[i]+jinwei-96);
13         if(temp>=10)
14         {
15             temp=temp-10;
16             jinwei=1;
17         }
18         else jinwei=0;
19         result[i]=(char)(temp+48);
20     }

减法算法:

 1     int i=0;
 2     int temp=0;
 3     int jiewei=0;
 4     int len=0;
 5     int ret=1;
 6
 7     while(tempbuf1[i]!=‘\0‘)    // tempbuf1 和 tempbuf2 的长度相等
 8     {
 9         len++;
10         i++;
11     }
12
13     ret = Compare(tempbuf1,tempbuf2);
14     if(ret==1)
15     {
16         for(i=len-1;i>=0;i--)
17         {
18             temp = (int)tempbuf1[i] - (int)tempbuf2[i] - jiewei;
19             if (temp>=0)
20             {
21                 result[i]=(char)(temp+48);
22                 jiewei=0;
23             }
24             else if (temp<0)
25             {
26                 result[i]=(char)(temp+10+48);
27                 jiewei=1;
28             }
29         }
30         ThrowAway_0 (result);
31     }
32     else if(ret==0)
33     {
34         memset(result,0,100001);
35         result[0]=‘0‘;
36     }
37     else if(ret==-1)
38     {
39         for(i=len-1;i>=0;i--)
40         {
41             temp = (int)tempbuf2[i] - (int)tempbuf1[i] - jiewei;
42             if (temp>=0)
43             {
44                 result[i]=(char)(temp+48);
45                 jiewei=0;
46             }
47             else if (temp<0)
48             {
49                 result[i]=(char)(temp+10+48);
50                 jiewei=1;
51             }
52         }
53         ThrowAway_0 (result);
54         memset(buf1,0,100001);
55         sprintf(buf1,"-%s",result);
56         strcpy(result,buf1);
57     }
58     

在对减法进行运算时,存在大数减小数的问题,因此需要对字符串长度进行比较:

比较函数如下:

 1 int Compare(char *tempbuf1,char *tempbuf2)
 2 {
 3     ThrowAway_0 (tempbuf1);
 4     ThrowAway_0 (tempbuf2);
 5     char buf1[100001]={0};
 6     char buf2[100001]={0};
 7     Trans(tempbuf1,tempbuf2,buf1,buf2);
 8     memset(tempbuf1,0,100001);
 9     memset(tempbuf2,0,100001);
10     strcpy(tempbuf1,buf1);
11     strcpy(tempbuf2,buf2);
12
13
14     int ret=1;
15     int count=0;
16     while(count<100001)
17     {
18
19         int m=(int)tempbuf1[count]-48;
20         int n=(int)tempbuf2[count]-48;
21         if(m==n)
22         {
23             count++;
24             ret=0;
25         }
26         else if(m>n)
27         {
28         //    printf("tempbuf1>tempbuf2\n");
29             ret=1;
30             break;
31
32         }
33         else if(m<n)
34         {
35         //    printf("tempbuf1<tempbuf2\n");
36             ret=-1;
37             break;
38         }
39     }
40     return ret;
41 }

4:对多余项进行缩减:

将剩余0去掉

 1 void  ThrowAway_0 (char *tempbuf )  // 去除结果前面的 连续的无意义的 "0"
 2 {
 3     char buf[100000]={0};
 4
 5     int n = strlen(tempbuf)-1;
 6     int i=0;
 7     while(i<n)
 8     {
 9         if (tempbuf[i]!=‘0‘)
10         {
11             break;
12         }
13         else
14         {
15             i++;
16         }
17     }
18     int Throw = i;
19     for (i=0;i<=n-Throw;i++)
20     {
21         buf[i]=tempbuf[i+Throw];
22     }
23
24     strcpy(tempbuf,buf);
25
26 }

5:对结果进行输出 完成。

测试代码如下:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

void Add (char *tempbuf1,   char *tempbuf2, char *result);  // 大数相加 result = tempbuf1 + tempbuf2

void Sub(char *tempbuf1, char *tempbuf2, char *result);     // 大数相减 result = tempbuf1 - tempbuf2 (默认前者大) 

void Trans (char *str_num1,   char *str_num2, char *tempbuf1, char *tempbuf2); // 大数转化为等长,且最前面添加 “0”

int Compare(char *tempbuf1,char *tempbuf2);//比较两个字符串的长度 相同返回0 buf1长返回1 buf2长返回-1

void  ThrowAway_0 (char *tempbuf );  // 去除结果前面的 连续的无意义的 "0"

int main()
{

	char str1[100001];
	char str2[100001];
	char result[100001]={0};
	short result_flag = 0;

	scanf("%s %s",str1,str2);

	if(str1[0] == ‘-‘ && str2[0] == ‘-‘)
	{
		str2[0] = str1[0] = ‘0‘;
		Add(str1,str2,result);
		if(result[0]!= ‘0‘)
		{
			printf("-");
			printf("%s\n",result);
		}

		else
		printf("0\n");
	}
	else if(str1[0]  == ‘-‘ && str2[0] != ‘-‘)
	{
		str1[0] =‘0‘;

		Sub(str2,str1,result);
		printf("%s\n",result);
	}
	else if(str1[0] != ‘-‘ && str2[0] == ‘-‘)
	{
		str2[0] = ‘0‘;
		Sub(str1,str2,result);
		printf("%s\n",result);
	}
	else
	{
		Add(str1,str2,result);
		printf("%s\n",result);
	}

	return 0;
}

void Trans(char *str_num1, char *str_num2, char *tempbuf1, char *tempbuf2)
{
	int len_num1=0;
	int len_num2=0;
	int i=0;
	while(str_num1[i]!=‘\0‘)
	{
		len_num1++;
		i++;
	}
	i=0;
	while(str_num2[i]!=‘\0‘)
	{
		len_num2++;
		i++;
	}	

	tempbuf1[0]=‘0‘;
	tempbuf2[0]=‘0‘;

//=======================================================================
	if(len_num2>=len_num1)                                   //补成相同长度
	{
		for(i=1;i<=(len_num2-len_num1);i++)
		{
			tempbuf1[i]=‘0‘;
		}
		for(i=len_num2-len_num1+1;i<=len_num2;i++)
		{
			tempbuf1[i]=str_num1[i-(len_num2-len_num1+1)];
		}
		for(i=1;i<=len_num2;i++)
		{
			tempbuf2[i]=str_num2[i-1];
		}
	}
//------------------------------------------
	else if(len_num2<len_num1)
	{
		for(i=1;i<=(len_num1-len_num2);i++)
		{
			tempbuf2[i]=‘0‘;
		}
		for(i=len_num1-len_num2+1;i<=len_num1;i++)
		{
			tempbuf2[i]=str_num2[i-(len_num1-len_num2+1)];
		}
		for(i=1;i<=len_num1;i++)
		{
			tempbuf1[i]=str_num1[i-1];
		}
	}

}

void Add(char *tempbuf1,   char *tempbuf2, char *result) // 大数相加 result = tempbuf1 + tempbuf2
{
	char buf1[100001]={0};
	char buf2[100001]={0};
	Trans(tempbuf1,tempbuf2,buf1,buf2);
	strcpy(tempbuf1,buf1);
	strcpy(tempbuf2,buf2);

	int i=0;
	int temp=0;
	int jinwei=0;
	int len=0;
	while(tempbuf1[i]!=‘\0‘)
	{
		len++;
		i++;
	}
	for(i=len-1;i>=0;i--)
	{
		temp=(int)(tempbuf1[i]+tempbuf2[i]+jinwei-96);
		if(temp>=10)
		{
			temp=temp-10;
			jinwei=1;
		}
		else jinwei=0;
		result[i]=(char)(temp+48);
	}
	ThrowAway_0 (result);

}

//================================================

void  ThrowAway_0 (char *tempbuf )  // 去除结果前面的 连续的无意义的 "0"
{
	char buf[100000]={0};

	int n = strlen(tempbuf)-1;
	int i=0;
	while(i<n)
	{
		if (tempbuf[i]!=‘0‘)
		{
			break;
		}
		else
		{
			i++;
		}
	}
	int Throw = i;
	for (i=0;i<=n-Throw;i++)
	{
		buf[i]=tempbuf[i+Throw];
	}

	strcpy(tempbuf,buf);

}

//=======================================================

//extern "C" __declspec(dllexport)
void Sub(char *tempbuf1, char *tempbuf2, char *result)     // 大数相减 result = tempbuf1 - tempbuf2
{
	ThrowAway_0 (tempbuf1);
	ThrowAway_0 (tempbuf2);
	memset(result,0,200);
	char buf1[100001]={0};
	char buf2[100001]={0};
	Trans(tempbuf1,tempbuf2,buf1,buf2);
	memset(tempbuf1,0,100001);
	memset(tempbuf2,0,100001);

	strcpy(tempbuf1,buf1);
	strcpy(tempbuf2,buf2);

	int i=0;
	int temp=0;
	int jiewei=0;
	int len=0;
	int ret=1;

	while(tempbuf1[i]!=‘\0‘)    // tempbuf1 和 tempbuf2 的长度相等
	{
		len++;
		i++;
	}

	ret = Compare(tempbuf1,tempbuf2);
	if(ret==1)
	{
		for(i=len-1;i>=0;i--)
		{
			temp = (int)tempbuf1[i] - (int)tempbuf2[i] - jiewei;
			if (temp>=0)
			{
				result[i]=(char)(temp+48);
				jiewei=0;
			}
			else if (temp<0)
			{
				result[i]=(char)(temp+10+48);
				jiewei=1;
			}
		}
		ThrowAway_0 (result);
	}
	else if(ret==0)
	{
		memset(result,0,100001);
		result[0]=‘0‘;
	}
	else if(ret==-1)
	{
		for(i=len-1;i>=0;i--)
		{
			temp = (int)tempbuf2[i] - (int)tempbuf1[i] - jiewei;
			if (temp>=0)
			{
				result[i]=(char)(temp+48);
				jiewei=0;
			}
			else if (temp<0)
			{
				result[i]=(char)(temp+10+48);
				jiewei=1;
			}
		}
		ThrowAway_0 (result);
		memset(buf1,0,100001);
		sprintf(buf1,"-%s",result);
		strcpy(result,buf1);
	}

}

//======================================================================

//===================================================================================

int Compare(char *tempbuf1,char *tempbuf2)
{
	ThrowAway_0 (tempbuf1);
	ThrowAway_0 (tempbuf2);
	char buf1[100001]={0};
	char buf2[100001]={0};
	Trans(tempbuf1,tempbuf2,buf1,buf2);
	memset(tempbuf1,0,100001);
	memset(tempbuf2,0,100001);
	strcpy(tempbuf1,buf1);
	strcpy(tempbuf2,buf2);

	int ret=1;
	int count=0;
	while(count<100001)
	{

		int m=(int)tempbuf1[count]-48;
		int n=(int)tempbuf2[count]-48;
		if(m==n)
		{
			count++;
			ret=0;
		}
		else if(m>n)
		{
		//	printf("tempbuf1>tempbuf2\n");
			ret=1;
			break;

		}
		else if(m<n)
		{
		//	printf("tempbuf1<tempbuf2\n");
			ret=-1;
			break;
		}
	}
	return ret;
}

此外,对于大数运算不限于加减运算 更多运算方法可以参考大数模板:

c++大数模板

参考内容:

参考博客

时间: 2024-10-06 16:15:20

【51Nod】1005 大数加法的相关文章

51nod 1005 大数加法

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 Input 第1行:大数A 第2行:大数B (A,B的长度 <= 10000 需注意:A B有可能为负数) Output 输出A + B Input示例 68932147586 468711654886 Output示例 537643802472 Java在处理大数据方面很具有优势~~~~~~~~~~~~~~~~~~~ import java.math.BigInteger; import java.util.Scan

51 Nod 1005 大数加法【Java大数乱搞,python大数乱搞】

1005 大数加法 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 给出2个大整数A,B,计算A+B的结果. Input 第1行:大数A 第2行:大数B (A,B的长度 <= 10000 需注意:A B有可能为负数) Output 输出A + B Input示例 68932147586 468711654886 Output示例 537643802472 题目链接:http://www.51nod.com/onlineJudge/questionCode.html#

1005 大数加法

1005 大数加法 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 给出2个大整数A,B,计算A+B的结果. Input 第1行:大数A 第2行:大数B (A,B的长度 <= 10000 需注意:A B有可能为负数) Output 输出A + B Input示例 68932147586 468711654886 Output示例 537643802472 c++代码 1 #include <iostream> 2 #include <cstring&g

51nod基础题感触(1005大数加法)

这篇就作为算法学习这块的第一篇文章啦!之前一直想来写一下博客来着,但是自己太懒了,建模比赛后想多休息(玩)一会儿(很长时间),一直没写.最近总算是下定决定了! “的确是要开始写一写最近自己做题的感受了!”(超认真的!) 直入正题!(由于才正式开始学习,理解有不足之处还请指正!) 首先,遇到这样的题,如果不限制语言的话,抱着能快则快的心态,我们就用强大的Python就行了.实现起来也是十分地的简单,在这里,我就直接上代码啦!(这里我用的是Python3.6) a=input()#输入,这时候的a实

大数加法、大数乘法

大数加法 hdu1002 #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <cmath> #include <sstream> #include <algorithm> #include <set> #include <map> #include <vector> #i

C语言 &#183; 大数加法

算法提高 大数加法 时间限制:1.0s   内存限制:256.0MB 问题描述 输入两个正整数a,b,输出a+b的值. 输入格式 两行,第一行a,第二行b.a和b的长度均小于1000位. 输出格式 一行,a+b的值. 样例输入 42 样例输出 6 1 #include<stdio.h> 2 #include<string.h> 3 int main() 4 { 5 char a[1001],b[1001]; 6 int s[1001],d[1001]; 7 scanf("

NI笔试——大数加法

NI笔试: 1.找出字符串第一次出现的字符.用数组建立哈希表,然后再扫描字符串并判断次数是否为1. 2.大数加法,即字符串加法.因为之前写过乘法,就以为是乘法.然后就把乘法写上去了····= = 好了,看一下加法的思路. 要不要太简单,用俩数组,先把字符串每个位转换成数字存到这俩数组里,然后对每一位进行加和. 代码是拿别人的.= = void Add(char s1[],char s2[]) //需要两个字符串参数&&无返回值 { int num1[M],nm2[M]; int i,j;

大数加法、乘法

1 #include<iostream> 2 3 #include<stdio.h> 4 5 #include<string.h> 6 7 #define Len 3000//大数的长度 8 9 using namespace std; 10 11 int Input (char n[])//将大数读入的函数 12 13 { 14 15 char s[Len]; 16 17 int i,l; 18 19 20 21 for(i=0; i<Len; i++) n[i

A + B Problem II(大数加法)

一直格式错误,不想改了,没A 1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <stdlib.h> 5 using namespace std; 6 7 int main() 8 { 9 int T,K=0; 10 scanf("%d",&T); 11 char a[1002],b[1002]; 12 int ta[1002],