51Nod1005 大数加法
Posted KID_XiaoYuan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51Nod1005 大数加法相关的知识,希望对你有一定的参考价值。
给出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; }
此外,对于大数运算不限于加减运算 更多运算方法可以参考大数模板:
参考内容:
以上是关于51Nod1005 大数加法的主要内容,如果未能解决你的问题,请参考以下文章