js分治算法實現大整數相加、相減


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM