两个大数相加

如何计算两个超出 int64 的整数呢?

正常情况下,使用 int 时是有长度限制的,超出就溢出了,但是字符串可就没有这个限制了,因此可以往字符串这个方向考虑。

比如 “123456789” 这个字符串,里面的每个字符都是 ASCII 码,字符类型 9 如何转换成整数类型的 9 呢,下面贴出下 ASCII 码的对照表。
两个大数相加_第1张图片
看上图圈红的地方,字符 9 转换为整数 9 只需 ‘9’ - ‘0’ = 57 - 48 = 9 即可。

这样一来,大数相加就可用转换为 ASCII 码和相加进位的问题。

但是两个字符串相加也要讲究技巧,因为不知道长度,比如 “123456789” 和 “123” 相加,咱们惯用的方法是个位、十位等依次相加,再加上对应的进位即可,那么这里也可以如此实现,就是上面可以看成两个字符串数组,那么相加的时候,依次获取最后一位相加,一旦某个字符串长度归 0 了,那么就相加结束了。

干这么说,还是不怎么明显,下面简单演示下。

// 表示进位
int carry = 0;

// 存储相加的结果
int temp = ('9' - '0') + ('3' - '0') + carry; // 12

// 获取进位
carry = temp / 10; // 1

// 获取结果
temp = temp % 10; // 2

这里还有一点需要注意,就是保存的结果,由于是从最右边开始计算,结果是这样 219654321 的,也就是反着的,最后需要反转下,变成 123456912 真正的结果。

下面给出 C 的解题方法。

#include 
#include 
#include 

char *reverse(char *str) {
    int len = strlen(str);
    char *res = malloc(len+1);
    int i =0;
    len -= 1;
    for (; len >= 0; len--) {
        res[i++] = str[len];
    }
    return res;
}

char *append(char *str, int c) {
    int len;
    if (str == NULL) {
        len = 0;
    } else {
        len = strlen(str);
    }
    char *res = malloc(len+1);
    if (str != NULL) {
        memcpy(res, str, len);
    }
    res[len]  = c + '0'; // 这里需要注意,传进来的是数字,那么需要其加 '0' 转成字符
    res[len+1] = '\0';
    return res;
}

char *add(char *str1, char *str2) {
    int carry = 0;
    int len1 = strlen(str1);
    int len2 = strlen(str2);
    char *res = NULL;
    len1 -= 1;
    len2 -= 1;
    while (len1 >= 0 || len2 >= 0) {
        int n1 = len1 >= 0 ? str1[len1] - '0' : 0;
        int n2 = len2 >= 0 ? str2[len2] - '0' : 0;
        int temp = n1 + n2 + carry;
        carry = temp / 10;
        res = append(res, temp % 10);
        len1--;
        len2--;
    }
    if (carry == 1)
        res = append(res, 1);
    res = reverse(res);
    return res;
}

int main() {

    char *str1 = "123456789";
    char *str2 = "123";
    char *res = add(str1, str2);

    printf("res is %s\n", res);

    return 0;
}

当然了,若是使用 Java 的话,更加快捷方便。

    public String add(String num1, String num2) {
        StringBuilder res = new StringBuilder("");
        int i = num1.length() - 1, j = num2.length() - 1, carry = 0;
        while(i >= 0 || j >= 0){
            int n1 = i >= 0 ? num1.charAt(i) - '0' : 0;
            int n2 = j >= 0 ? num2.charAt(j) - '0' : 0;
            int tmp = n1 + n2 + carry;
            carry = tmp / 10;
            res.append(tmp % 10);
            i--; j--;
        }
        if(carry == 1) res.append(1);
        return res.reverse().toString();
    }

【参考】

面试算法题(2)–两个大数相加

你可能感兴趣的:(LeetCode)