• HDU 1002 (高精度加法运算)


    A + B ProblemII

    Time Limit: 2000/1000 MS(Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 317773    Accepted Submission(s):61748


    Problem Description

    I have a verysimple problem for you. Given two integers A and B, your job is to calculatethe Sum of A + B.

     

     

    Input

    The first line ofthe input contains an integer T(1<=T<=20) which means the number of testcases. Then T lines follow, each line consists of two positive integers, A andB. Notice that the integers are very large, that means you should not processthem by using 32-bit integer. You may assume the length of each integer willnot exceed 1000.

     

     

    Output

    For each testcase, you should output two lines. The first line is "Case #:", #means the number of the test case. The second line is the an equation "A +B = Sum", Sum means the result of A + B. Note there are some spaces intthe equation. Output a blank line between two test cases.

     

     

    Sample Input

    2

    1 2

    112233445566778899998877665544332211

     

     

    Sample Output

    Case 1:

    1 + 2 = 3

     

    Case 2:

    112233445566778899+ 998877665544332211 = 1111111111111111110

     

    题意简述

    首先输入一个数字T(1 <= T <= 20)代表输入的数据组数,其次下边有T行,每行有2个欲求和的数字,并且每个数字不超过1000位。

     

    题意分析

    这是一道高精度数字计算的题目,unsigned long long double 是不能满足所需要的数字位数的,所以需要别的方法进行计算。

     

    解题思路

    1.  首先用2个字符串接受并储存要输入的2个加数;

    2.  去掉前导零

    3.  按照ASCII的关系,让字符串的每个字符减去字符0,获得数值并且倒置存储在2个数组中;

    4.  模拟加法运算,并储存在另一个数组中;

    5.  按要求输出结果;

    6.  初始化各个数据

     

    测试数据补充

    0001 1000

    0 0

    000 0000

    9999 1

    1 9999

    99900 00999

    00999 99900

    当然还有大位数的极端数据,这些能过基本上就不会WA了。

     

    代码总览

    #include<stdio.h>
    #include<string.h>
    #define max(x,y)  ( x>y?x:y )
    #define n 1010
    int main()
    {
    	//freopen("in.txt", "r", stdin);
    	//freopen("out.txt", "w", stdout);
    	char a1[n]={0};
    	char b1[n]={0};
    	int a2[n]={0}, b2[n]={0};
    	int num ,n1,n2,j,digit,k,i,m1,m2;
    	scanf("%d", &num);
    	for(i = 1; i <=num; i++){
    		//n1 = n2 = j = digit = k = m1 = m2 = 0;
    		scanf("%s %s",a1,b1);
    		n1 = strlen(a1);
    		n2 = strlen(b1);
    		for(j = 0 ; j < n1; j++){
    			if(a1[j] != '0'&& a1[j] != NULL){
    				m1 = j;
    				break;
    			}else if(a1[j] == '0' && j == n1-1){
    				m1 = 0;
    				n1 = 1;
    				break;
    			}
    		}
    		for(j = 0 ; j < n2; j++){
    			if(b1[j] != '0' && b1[j] != NULL){
    				m2 = j;
    				break;
    			}else if(b1[j] == '0' && j == n2-1){
    				m2 = 0;
    				n2 = 1;
    				break;
    			}
    		}
    		for(j = n1-1,k = 0;j >=m1 ;j--,k++){
    			a2[k] = a1[j] - '0';
    		}
    		
    		for(j = n2-1,k = 0;j >=m2 ;j--,k++){
    			b2[k] = b1[j] - '0';
    		}
    		digit = max(n1-m1,n2-m2);
    		int c2[n] = {0};
    		for(j = 0; j < digit ; j++){
    			c2[j] = a2[j] + b2[j] + c2[j];
    			c2[j+1] = c2[j] / 10;
    			c2[j] = c2[j] % 10;
    		}
    		if(c2[digit] == 0) digit--;
    		printf("Case %d:
    ",i);
    		for(j = m1; j<n1;j++){
    			printf("%c",a1[j]);
    		}
    		printf(" + ");
    		for(j = m2; j<n2;j++){
    			printf("%c",b1[j]);
    		}
    		printf(" = ");
    		for(j = digit; j>= 0; j--) printf("%d",c2[j]);
    		if(i != num) {
    			printf("
    
    ");
    		}else{
    			printf("
    ");
    		}
    		for(j = 0; j<=digit; j++){
    			a2[j] = b2[j] = 0;
    		}
    	}
    	//fclose(stdin);
        //fclose(stdout);
    	return 0;
    }


     

    重难点详解

    1.  前导零的去除

           for(j = 0 ; j< n1; j++){

               if(a1[j]!= '0'&& a1[j] != NULL){

                  m1 =j;

                  break;

               }elseif(a1[j] == '0' && j == n1-1){

                  m1 =0;

                  n1 =1;

                  break;

               }

           }

    因为下一步要进行倒置处理,所以不妨从字符串的第一个字符开始遍历,遇到‘0’跳过,并使变量指向下一个字符,直到遍历到第一个不为零的字符,或者是遍历完整个字符串(说明全都是‘0’)。

    如字符串0302,遍历到第一个字符‘0’m1 为0,第二个字符不为0,所以m1为1,那么倒置字符串从第1位也就是3开始,这样就过滤了前导零。

    当然还有极端情况,就是0000…都为0的情况,这样当遍历完整个字符串后发现都是0,那么就规定m1为0,n1为1,进行下面的操作。

    2.  倒置

    for(j = n1-1,k = 0;j >=m1 ;j--,k++){

                         a2[k] =a1[j] - '0';

                  }

    很简单,字符减去字符0储存在一个新的数组中,不过注意下标的关系。我这里是从字符串的最后一位开始取储存在数组的第一位中。

    3.  模拟加法运算

    digit =max(n1-m1,n2-m2);

            int c2[n] = {0};

            for(j = 0; j < digit ; j++){

                   c2[j] = a2[j] + b2[j] + c2[j];

                   c2[j+1] = c2[j] / 10;

                   c2[j] = c2[j] % 10;

            }

    Digit变量是两个数组中位数较大的一个,因为要进行足够次数的加法算。新令一个数组来储存同一位的数字之和。并让下一位等于本位除以10(模拟进位),本位取10的余数。

     


  • 相关阅读:
    转载:混淆包含SlidingMenu、gson等Android代码的proguard写法
    今天解决的两个问题
    C++中指针和引用的区别
    负载均衡服务器session共享的解决方案 (转载)
    Entity Framework的默认值BUG解决方法
    【转】SAPI中的IspeechRecoContext(接口)
    Sapi 添加语法的文章(转载)
    SAPI训练文件存储位置
    Flask第九篇 Flask 中的蓝图(BluePrint)
    Flask 第八篇 实例化Flask的参数 及 对app的配置
  • 原文地址:https://www.cnblogs.com/pengwill/p/7367286.html
Copyright © 2020-2023  润新知