函数实现一个大位数乘法,可以计算出诸如1865459497823*6349526719336的结果
// 直接
1865459497823 * 6349526719336
1.1844784925266256e+25
ES6 BigInt
function multiplyBig(a, b) {
let A = BigInt(a), B = BigInt(b);
let res = A * B;
return res;
}
console.log(multiplyBig(3, 4))
console.log(multiplyBig(1865459497823, 6349526719336))
// 12n
// 11844784925266255224005528n
- num1 和 num2 的长度小于110。
- num1 和 num2 只包含数字 0-9。
- num1 和 num2 均不以零开头,除非是数字 0 本身。
- 不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理。
方法一: 实现相乘运算-竖乘(暴力)
时间复杂度 O(n^2)
需要辅助函数,字符串相加
注意: num1 cur问题在于,大数相乘精度丢失。需要实现 一位数一位数。'0'.repeat(3) // '000'
var multiply = function(num1, num2) {
if ([num1, num2].includes('0')) return '0';
let res = '';
const len1 = num1.length, len2 = num2.length;
for(let i = 0; i < len2;i++) {
let cur2 = num2.charAt(len2 - i - 1);
let tmp = '';
for(let j = 0; j < len1; j++) {
let cur1 = num1.charAt(len1 - j - 1);
tmp = addString(tmp, cur1 * cur2 + ('0'.repeat(j)));
// console.log(cur1, tmp);
}
res = addString(res, tmp + ('0'.repeat(i)));
}
return res
};
function addString(s1, s2) {
let nums1 = s1.split('').map(d => parseInt(d));
let nums2 = s2.split('').map(d => parseInt(d));
let res = [];
let tmp = 0;
while(nums1.length || nums2.length) {
let num1 = nums1.pop() || 0;
let num2 = nums2.pop() || 0;
let sum = num1 + num2 + tmp;
if (sum > 9) {
sum -= 10;
tmp = 1;
} else {
tmp = 0;
}
res.unshift(sum)
}
if (tmp) res.unshift(tmp);
return res.join('');
}
// @lc code=end
// console.log(multiply('0', '63'), '0')
// console.log(multiply('25', '63'), 1575)
// console.log(multiply('123', '456'), 56088)
// console.log(multiply('123456789', '987654321'), '121932631112635269')
// console.log(multiply('9333852702227987', '85731737104263'), '800207406037324579815815608581')
方式二:分治
➕ 为权重➕, 至于进位
AB=a1b110^n+(a1b0+b1a0)10^(2/n)+a0*b0
参考:
https://www.jianshu.com/p/b5af56d676b2
方式三:Karatsuba算法
时间复杂度:
伪代码
procedure karatsuba(num1, num2)
if (num1 < 10) or (num2 < 10)
return num1*num2
/* calculates the size of the numbers */
m = max(size_base10(num1), size_base10(num2))
m2 = m/2
/* split the digit sequences about the middle */
high1, low1 = split_at(num1, m2)
high2, low2 = split_at(num2, m2)
/* 3 calls made to numbers approximately half the size */
z0 = karatsuba(low1,low2)
z1 = karatsuba((low1+high1),(low2+high2))
z2 = karatsuba(high1,high2)
return (z2*10^(2*m2))+((z1-z2-z0)*10^(m2))+(z0)
**
参考:
https://mp.weixin.qq.com/s/GCCEJWbNscJyf4K5nleOnA
https://zh.wikipedia.org/wiki/Karatsuba%E7%AE%97%E6%B3%95
https://zhuanlan.zhihu.com/p/64631681