给定两个字符串形式的非负整数 num1
和num2
,计算它们的和并同样以字符串形式返回。
你不能使用任何內建的用于处理大整数的库(比如 BigInteger
), 也不能直接将输入的字符串转换为整数形式。
示例 1:
输入:num1 = "11", num2 = "123" 输出:"134"
示例 2:
输入:num1 = "456", num2 = "77" 输出:"533"
示例 3:
输入:num1 = "0", num2 = "0" 输出:"0"
提示:
1 <= num1.length, num2.length <= 104
num1
和num2
都只包含数字0-9
num1
和num2
都不包含任何前导零char* addStrings(char* num1, char* num2) { int i = strlen(num1) - 1, j = strlen(num2) - 1, add = 0; //i是num1长度,数组是从零开始故减1 //j同理 //add代表进位数 char* ans = (char*)malloc(sizeof(char) * (fmax(i, j) + 3)); //申请空间 //fmax函数是比较谁的位数多 //那么以多的位数为最后位数数 //多加3是为预防内存不够 int len = 0; while (i >= 0 || j >= 0 || add != 0) { //在存在有未加位数或者进位数时进行while int x = i >= 0 ? num1[i] - '0' : 0; int y = j >= 0 ? num2[j] - '0' : 0; //因为每次while要结束的时候都有--的操作 //所以只有大于零时才执行赋值 //也就是有数的时候赋值才能相加 //num1[i]-'0'时将整型变量转换成字符型变量 //否则返回0保持竖式算术的进行 //即遍历完当前字符串就加0 //让其他的字符串数组继续相加 //形如"456" // +"088" 这里0真是起到保持形式的作用 int result = x + y + add; //每次结果都是两数之和加上进位数 ans[len++] = '0' + result % 10; //这里的len++是先对ans[len]赋值 //再对len进行++ //这里的'0'+的操作也是为了进行转换 //取余10即得到个位数 add = result / 10; //这里进行完个位数相加后 //除10除去个位数以便进行下一位的相加 i--, j--; //随着除10那么元素少1故-- } // 计算完以后的答案需要翻转过来 for (int i = 0; 2 * i < len; i++) { //关于为什么是2*i //无论是偶数情况还是奇数情况 //每次交换位置都涉及到两个数 //如:12345 1换到5那么也相当于5被换到1 // 123456 同上 //奇数位时中间位不会动 //那也就是说被交换的位最多是len一半的个数 //所以2*i小于len是全部遍历的条件 //考虑到是从0位开始的 //所以2*i<len否则则可以等于len int t = ans[i]; ans[i] = ans[len - i - 1], ans[len - i - 1] = t; //ans[i]相当于末尾数 //ans[len-i-1]相当于首位数 //交换的时候是要有一个中间过渡量即t //没有过渡量会如何呢? //ans[i]=ans[len-i-1]的时候 //右边的给了左边的 //但是当左边要给右边时 //左边的值已经被改变了 //这样就无法完成交换了 } ans[len++] = 0; //考虑到前面有多分配空间 //故最后需加上0 //这里的0代表NULL //即终止字符的作用 //又相当于释放了多分配的内存 return ans; }