问题

如果相加的两个数位数过多,大于32位(int),大于64位(long),该如果计算?

解决方法

可以用两个字符数组去储存两个大数,然后就是字符相加

具体细节

先拿出草稿,默默的用两个大数,竖式算一遍,然后记住这个过程中过的细节,再转换为代码(也可以先看代码部分,代码部分有详细注释):

  1. 低位开始相加
    转换成代码思维:两个数组保存的数都是低索引保存高位,因此两种方法,一种先把两个数组反转,一种就是从数组最后一位开始计算
  2. 有进位
    在计算的过程中,如果低位相加大于10,需要把结果的余数作为此次结果,除以10的结果作为进位,此进位下次和高位的数相加。
  3. 两个数组的长度不一致
    在计算的过程中是两个数组对应位数的数再加上进位,如果加数已经加完了,那么就是被加数和进位相加就可以了
  4. 结果需要反转
    如果计算的过程中低位相加的结果放在结果数组的低索引中,最后需要把结果反转。

代码实现

#include <iostream>

//字符数组反转 
void reverseStr(char a[], int len_a) {
    int mid = len_a / 2;

    int i = 0, j = len_a - 1;
    char t;

//最后一位和第一位交换,倒数第二位和第二位交换.....
    for (int k = 0; k < mid; k++) {
        t = a[i];
        a[i] = a[j];
        a[j] = t;
        i++;
        j--;
        
    }
}

//字符数组相加
void strAdd(char output[],char a[], int len_a, char b[], int len_b) {
 // i 为加数 a[]的最后一位,j为被加数 b[]的最后一位
    int i = len_a - 1, j = len_b - 1;  
//c表示进位,个数相加的时候,进位是0
    int c = 0;
    int sum = 0;
    int k = 0;

//结果的位数为(len_a,len_b)中最大的数值或者此数值+1
    for (k = 0; k < len_a||k<len_b; k++) {
        sum = 0;
        if (k < len_a) {
         //先-‘0’ 变为int型,加上 加数
            sum += a[i] - '0'; 
            i--;
        }

        if (k < len_b) {
        // -‘0’变为int型,加上被加数
            sum += b[j] - '0'; 
            j--;
        }
        //加上进位
        sum += c;    
        //获取下一次计算的进位      
        c = sum / 10;
        //获取此位置上的数值结果,+‘0’ 从int型变为字符型
        output[k] = sum % 10 + '0';

        printf("temp[%d]=%c ", k, output[k]);
    }

// 最后c 为1,结果数值为max(len_a,len_b)+1
    if (c == 1) {
       //这个1需要
        output[k] = '1';
        //字符数组的最后加上'\0'
        output[k + 1] = '\0';
        //最后结果反转
        reverseStr(output, k + 1);
    }
    // 最后c 为0,结果数值为max(len_a,len_b)
    else {
      //字符数组的最后加上'\0'
        output[k] = '\0';
      //字符数组的最后加上'\0'  
        reverseStr(output, k);
    }
  
}


int main()
{
    char result[1000];
    char str1[100] = { '3','5','8','7','9','1'};
    char str2[100] = { '5','9','9','6','5','5','7'};
    
    strAdd(result,str1, 6, str2,7);
    char* str3 = result;

    while (*str3 != '\0') {
        printf("%c", *str3);
        str3++;
    }
    printf("\n");

    return 0;
}

运行结果

写一个大数相加的算法java 算法 大数相加_算法

调式注意的地方

1, 代码中i,j,k的数值变化是否正确
2. 加数和被加数都加完了,是否考虑了最后一次的进位
3. 在相加的时候是否转成了int型,结果是否转回成字符型

代码实现技巧

  1. 每次不是加数+被加数+进位一起加,而是判断,如果加数没有加完,加上;如果被加数没有加完,加上;
  2. 加数和被加数刚开始没有反转,而是从最后一位开始

总结

大数加法,大数减法,大数乘法,大数除法这些都没有用到什么特别的算法或者想不到的技巧,更考验算法的基本功。做算法千万不能看一眼,感觉会了就可以了;需要自己练,敲代码,调式出来了,还有以后碰到这个可以很快的写出来,这样就是会了。