如何计算两个超出 int64 的整数呢?
正常情况下,使用 int 时是有长度限制的,超出就溢出了,但是字符串可就没有这个限制了,因此可以往字符串这个方向考虑。
比如 “123456789” 这个字符串,里面的每个字符都是 ASCII 码,字符类型 9 如何转换成整数类型的 9 呢,下面贴出下 ASCII 码的对照表。
看上图圈红的地方,字符 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 <stdio.h>
#include <string.h>
#include <stdlib.h>
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();
}
【参考】