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
