网上有不少关于JS实现JS大数相加的教程,我就不一一列举了,但是我发现好几篇都有坑,其中一个差点把我摔死.....,本来按照他们的思路是没有问题的,但是今天在力扣上面刷题发现有些版本其实存在一个很大的bug.
一:为什么要用大数相加?大数相加是什么?
自行百度
二:网上教程原理复现
1:将要相加的两个数转换成字符串
2:比较两个字符串的位数,短的那一个字符串前面补0
3:逐位相加,判断是否存在进位
经过这一番操作之后,你会发现,你真的解决了这个问题,我也是这么认为
的,直到我在力扣上刷,一直提交一直不过,后来自己用上面的用例,发现.....这个方法是存在bug的,出现bug的关键点是你没有考虑到两数相加之后整体的进位,.什么意思呢?
我举个栗子,假如我用9999999999999+8,进行补齐操作,就是9999999999999+0000000000008,你进行操作之后,结果的位数是多少,是13,但是真正的结果位数是多少,是14位.为什么会造成这个结果?因为你首位(最高位)存在一个进位1,也就是carry=1,这个carry本该传递到下一次相加的,但是由于你一开始就限制了位数,没考虑到进位,此时已经是循环的终点了,这个时候这个进位就被丢弃了,显然你不可能拿到正确的结果.
三:解决办法
解决办法其实很简单,前面提到的版本解决办法是,在短的那一个前面补零,从而与长的保持位数相等,这里的解决办法是,加入长的那一个数字位数是l,我此时将长短都补零,使他们的位数变成l+1位,这样下来,就完美解决了由于进位导致的问题.
四:附代码
代码写的不好,大神轻点喷..
<script>
var addTwoNumbers = function (l1, l2) {
var l = Math.max(l1.length, l2.length)
var str1 = l1.join("").padEnd(l + 1, 0);
var str2 = l2.join("").padEnd(l + 1, 0);
console.log(str1, str2, l);
var carry = 0
var n = 0;
var arr = []
for (var i = 0; i < l + 1; i++) {
var sum = Number(str1[i]) + Number(str2[i])
if (sum >= 10) {
n = sum % 10 + carry;
arr.push(n);
carry = 1;
}
else if (sum == 9 && carry == 1) {
n = 0;
arr.push(n);
carry = 1;
}
else {
n = sum + carry;
arr.push(n);
carry = 0;
}
}
return arr
};
</script>