一、题目描述
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
二、分析
- 题目明确了是非负整数,所以不用考虑正负相乘的情况
- 如果num1或者num2超过了js整数的安全范围就会导致精度丢失,所以这里用字符串来表示整数,防止精度丢失
- 比较num1和num2长度,用较短长度的数字从后往前逐一和较长的数字相乘,并把相乘之后的结果记录到数组对应的位置
- 将数组中的每一项相加,这里要考虑大数相加超过安全范围的问题,也需要转化成字符串相加
- 考虑num1或者num2为0的情况,需要将最后的结果再去掉除最后一位外前面连续的0
三、实现代码
// 大数相加
function bigAdd(a, b) {
const aLen = a.length;
const bLen = b.length;
const maxLen = Math.max(aLen, bLen);
const fillA = a.padStart(maxLen, '0');
const fillB = b.padStart(maxLen, '0');
let sum = 0;
let carry = 0;
let result = '';
for (let i = maxLen - 1; i >= 0; i--) {
sum = Number(fillA[i]) + Number(fillB[i]) + carry;
const isBeyond10 = sum >= 10;
carry = isBeyond10 ? 1 : 0;
sum = isBeyond10 ? sum - 10 : sum;
result = `${sum}${result}`;
}
if (carry !== 0) {
return `${carry}${result}`;
}
return result;
}
function bigMultipyItem(many, one) {
const len = many.length;
let temp = 0;
let carry = 0;
let result = '';
for (let i = len - 1; i >= 0; i--) {
temp = Number(many[i]) * Number(one) + carry;
carry = Math.floor(temp / 10);
result = `${temp % 10}${result}`;
}
if (carry !== 0) {
return `${carry}${result}`;
}
return result;
}
function removeZero(str) {
let count = 0;
const len = str.length;
while (str[count] === 0 && count < len - 1) {
count++;
}
return str.substring(count, len);
}
function bigMultipy(a, b) {
const aLen = a.length;
const bLen = b.length;
if (aLen < bLen) {
return bigMultipy(b, a);
}
const multipyArray = [];
let count = 0;
for (let i = bLen - 1; i >= 0; i--) {
const multipyItem = bigMultipyItem(a, b[i]);
multipyArray[count] = multipyItem.padEnd(multipyItem.length + count, '0');
count++;
}
let result = multipyArray[0];
for (let i = 1; i < multipyArray.length; i++) {
result = bigAdd(result, multipyArray[i]);
}
return removeZero(result);
}