js分治算法实现大整数相加,算法复杂度为O(n/15)
js分治算法实现大整数相减,算法复杂度为O(n/15)+比较大小0-n/15;
//从字符截取数字
function getMidNum(str,start,len) {
if(start+len>0){
return +str.substr(start<0?0:start,start<0?start+len:len);
}else{
return 0;
}
}
//比较两个大整数的大小,返回-1,0,1
function bigNumCompare(a,b) {
let back=0;
let max=Math.ceil(Math.max(a.length,b.length)/15);
//分成多少段,从左边开始
for(let i=max;i>0;i--){
const num1=getMidNum(a,a.length-i*15,15);
const num2=getMidNum(b,b.length-i*15,15);
//15位数字相减
let cur=num1-num2;
if(cur<0){
back=-1;
break
}else if(cur>0){
back=1;
break
}
}
return back;
}
/*js分治算法实现大整数相加,算法复杂度为O(n/15)
* 1、整数的精度是Math.pow(2,53),大于 9007199254740992 的可能会丢失精度,所以相加的字符长度为15位。
* 2、负数+负数、负数+正数、正数+负数的情况
* */
function bigNumAdd(a,b){
if(a[0]==='-'&&b[0]==='-'){
return '-'+bigNumAdd(a.substr(1),b.substr(1))
}else if(a[0]==='-'){
return bigNumSub(b,a.substr(1))
}else if(b[0]==='-'){
return bigNumSub(a,b.substr(1))
}
let res='';
let temp=0;
let len1=a.length;
let len2=b.length;
let n=Math.ceil(Math.max(len1,len2)/15);
//分成多少段
for(let i=1;i<n+1;i++){
const num1=getMidNum(a,len1-i*15,15);
const num2=getMidNum(b,len2-i*15,15);
//15位数字相加
let strTemp= String(temp+ num1 + num2);
if(i!==n){
//异常1:处理000000000000000+整数的异常情况
if(strTemp.length<15){
strTemp='0'.repeat(15-strTemp.length)+strTemp;
res=strTemp+res;
temp=0;
continue;
}
//异常2:15位相加等于16位
if(strTemp.length===16){
res=strTemp.substr(1,15)+res;
temp=1;
continue;
}
}
//相加后的结果放入res前面
res=strTemp+res;
temp=0;
}
return res;
}
//大整数相减,处理 负数-负数、负数-正数、正数-负数的情况
function bigNumSub(a,b){
if(a[0]==='-'&&b[0]==='-'){
return bigNumSub(b.substr(1),a.substr(1))
}else if(a[0]==='-'){
return '-'+bigNumAdd(a.substr(1),b)
}else if(b[0]==='-'){
return bigNumAdd(a,b.substr(1))
}
let symb='';
if(bigNumCompare(a,b)<0){
symb='-';
const cache=a;
a=b;
b=cache;
}
let res='';
let temp=0;
let n=Math.ceil(a.length/15);
//分成多少段
for(let i=1;i<n+1;i++){
const num1=getMidNum(a,a.length-i*15,15);
const num2=getMidNum(b,b.length-i*15,15);
//15位数字相减
let tempNum=num1 - num2-temp;
if(tempNum<0){
temp=1;
tempNum=1000000000000000+tempNum;
}else{
temp=0;
}
let strTemp= String(tempNum);
if(i!==n){
//异常1:处理000000000000000+整数的异常情况
if(strTemp.length<15){
strTemp='0'.repeat(15-strTemp.length)+strTemp;
}
}
//相加后的结果放入res前面
res=strTemp+res;
}
return symb+res;
}
//45位
const a='-108900000000000000000000000000000';
const b='-1';
const c='1234567890123456789012345678901234567890';
console.log(bigNumSub(a,b))
// console.log(bigNumAdd(a,a))
// console.log(bigNumAdd(c,b))
测试
const a='-108900000000000000000000000000000';
const b='-1';
const c='-1234567890123456789012345678901234567890';
console.log(bigNumSub(a,b))
console.log(bigNumAdd(a,a))
console.log(bigNumAdd(c,b))
输出结果:
-108899999999999999999999999999999
-217800000000000000000000000000000
-1234567890123456789012345678901234567891
Process finished with exit code 0