以下为ChatGPT自动生成的解答,正确与否请自行判断。
BFE.devAI解答 - JavaScript 代码题
77. 实现 BigInt 的减法(含符号)
思路:
实现大整数减法的操作和大整数加法操作类似,都是从个位数开始进行操作,将当前位上的数字相减得到当前位的差,若前一位需要借位,则从前一位减去1。同时还需要考虑两个数的正负号以及结果的正负号,思路如下:
分别判断两个数的正负性,并将其转化为同号相加的形式,即确保第一个数为正数,第二个数为负数。
判断两个数的绝对值大小,确保第一个数大于等于第二个数。
从个位数开始,分别计算当前位上的数字差(后一个数为负数,实际操作为加法),并更新结果数组与是否需要借位的标志。
最后根据是否需要借位以及结果的正负号得到最终的结果。
代码实现如下:
function substract(a, b) {
const arr1 = a.split('');
const arr2 = b.split('');
let sign1 = 1, sign2 = 1;
let len1 = 0, len2 = 0;
let i = 0, j = 0;
// 判断正负号并转化为同号相加的形式
if (arr1[0] === '-') {
sign1 = -1;
i = 1;
}
if (arr2[0] === '-') {
sign2 = -1;
j = 1;
}
// 计算两个数的绝对值长度
len1 = arr1.length - (sign1 === -1 ? 1 : 0);
len2 = arr2.length - (sign2 === -1 ? 1 : 0);
// 为两个数的绝对值长度不足的高位补 0
if (len1 < len2) {
arr1.unshift(...Array(len2 - len1).fill('0'));
len1 = len2;
} else if (len1 > len2) {
arr2.unshift(...Array(len1 - len2).fill('0'));
len2 = len1;
}
const res = Array(len1).fill(0);
// 判断两个数的大小,确保第一个数大于等于第二个数
if (sign1 === -1 && sign2 === -1) {
if (arr1.join('') < arr2.join('')) {
[arr1, arr2] = [arr2, arr1];
[sign1, sign2] = [sign2, sign1];
}
} else if (sign1 === -1 && sign2 === 1) {
[arr1, arr2] = [arr2, arr1];
[sign1, sign2] = [sign2, sign1];
} else if (sign1 === 1 && sign2 === -1) {
if (arr1.join('') < arr2.join('')) {
[arr1, arr2] = [arr2, arr1];
[sign1, sign2] = [sign2, sign1];
}
}
let borrow = false; // 是否需要借位
// 从个位数开始计算
for (let k = len1 - 1; k >= 0; k--) {
let num1 = Number(arr1[k]);
let num2 = Number(arr2[k]);
if (borrow) {
num1 -= 1;
borrow = false;
}
if (sign1 === -1) num1 = -num1;
if (sign2 === -1) num2 = -num2;
let diff = num1 + num2;
if (diff < 0) {
diff += 10;
borrow = true;
}
if (sign1 === -1) diff = -diff;
res[k] = diff;
}
// 判断是否需要借位
if (sign1 === -1 && sign2 === -1 && borrow) {
for (let k = len1 - 1; k >= 0; k--) {
if (res[k] === 0) {
res[k] = 9;
} else {
res[k] -= 1;
break;
}
}
}
// 去除结果中高位的 0
while (res[0] === 0 && res.length > 1) {
res.shift();
}
// 组合结果字符串
let resStr = '';
if (sign1 === -1 && (sign2 === -1 || sign2 === 1 && arr1.join('') < arr2.join(''))) {
resStr = '-';
}
resStr += res.join('');
return resStr;
}
测试代码:
console.log(substract('-999999999999999999', '-1')); // -999999999999999998
console.log(substract('-999999999999999999', '+1')); // -1000000000000000000
console.log(substract('-999999999999999999', '0')); // -999999999999999999
console.log(substract('999999999999999999', '-999999999999999999')); // "2000000000000000000"
console.log(substract('999999999999999999', '+999999999999999999')); // '0'
console.log(substract('-999999999999999999', '-999999999999999999')); // '0'
console.log(substract('+999999999999999999', '+999999999999999999')); // '1999999999999999998'
console.log(substract('0', '0')); // '0'
时间复杂度:$O(n)$,其中 $n$ 表示两个数的绝对值的长度。
空间复杂度:$O(n)$,其中 $n$ 表示两个数的绝对值的长度。