zoukankan      html  css  js  c++  java
  • 【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]!='')
     7     {
     8         len_num1++;
     9         i++;
    10     }    
    11 //    printf("字符串1的长度: length1=%d
    ",len_num1);
    12     i=0;
    13     while(str_num2[i]!='')
    14     {
    15         len_num2++;
    16         i++;
    17     }    
    18 //    printf("字符串2的长度: length2=%d
    
    ",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]!='')
     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]!='')    // 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
    ");
    29             ret=1;
    30             break;
    31             
    32         }
    33         else if(m<n)
    34         {
    35         //    printf("tempbuf1<tempbuf2
    ");
    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
    ",result);
    		}
    		
    		else
    		printf("0
    ");
    	}
    	else if(str1[0]  == '-' && str2[0] != '-')
    	{
    		str1[0] ='0';
    
    		Sub(str2,str1,result);
    		printf("%s
    ",result);
    	}
    	else if(str1[0] != '-' && str2[0] == '-')
    	{
    		str2[0] = '0';
    		Sub(str1,str2,result);
    		printf("%s
    ",result);
    	}
    	else
    	{
    		Add(str1,str2,result);
    		printf("%s
    ",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]!='')
    	{
    		len_num1++;
    		i++;
    	}	
    	i=0;
    	while(str_num2[i]!='')
    	{
    		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]!='')
    	{
    		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]!='')    // 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
    ");
    			ret=1;
    			break;
    			
    		}
    		else if(m<n)
    		{
    		//	printf("tempbuf1<tempbuf2
    ");
    			ret=-1;
    			break;
    		}
    	}
    	return ret;
    }
    

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

    c++大数模板

    参考内容:

    参考博客

  • 相关阅读:
    金蝶用户组权限语句
    金蝶物料更改保质期控制状态
    cisco+pppoe拨号配置教程
    FormFile上传文件代码(修改)
    试用django 和 rgraph 简单记录
    一闪而过的远程桌面
    用 python matplotlib 画图 简单记录
    去除UTL_FILE导致的ORA12012 ORA04068 ORA04063 ORA06508
    python mysqldb模块安装
    canvas绘制圆形
  • 原文地址:https://www.cnblogs.com/KID-XiaoYuan/p/6287940.html
Copyright © 2011-2022 走看看