亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

大整數(shù)相乘 + 分治法(JS)

Keagan / 760人閱讀

摘要:使用分治法來實現(xiàn)大整數(shù)相乘相乘的基本原理如第一步分解和和第二步分別計算首部中部尾部第三步進(jìn)位因為是以兩位數(shù)字分割的,所以進(jìn)位是滿進(jìn)一位尾部留,進(jìn),即中部,留,進(jìn),即首部,即第四步重組首部中部尾部分治法思想將這樣的算式分解成和接下來使用遞

使用分治法來實現(xiàn)大整數(shù)相乘

相乘的基本原理

如: 1234 * 567
第一步:分解
   234 -> 12 和 34;
   567 -> 5 和 67;
第二步:分別計算 
   首部: 12*5=60
   中部:12*67+34*5=974
   尾部:34*67=2278
第三步:進(jìn)位(因為是以兩位數(shù)字分割的,所以進(jìn)位是滿100進(jìn)一位)
   尾部:留78,進(jìn)22,即78
   中部:974+22=996,留96,進(jìn)9,即96
   首部:60+9=69,即69
第四步:重組
   首部+中部+尾部:699678

分治法思想

2135415134543*4573756875685 這樣的算式分解成 2135415*4573756、2135415*875685+4573756*134543134543*875685,接下來使用遞歸再分解即可。

數(shù)據(jù)的對象類型

    如:123
    NumberObject {
        number:"321",
        length:3,
        sign:1
    }

注意事項
1、每個函數(shù)的用法源碼中有注釋
2、存貯的字符串是數(shù)字的倒序,如輸入"123",存儲為"321",計算時也是用"321"
3、測試函數(shù)為test(x,y),x和y必須為字符串類型才能進(jìn)行計算大整數(shù)的相乘

源代碼

    // 整數(shù)的構(gòu)造函數(shù)
    function NumberObject( string , sign ) {
        if( sign === -1){
    
            this.number = reverseString( string.slice(1) );
            this.length = string.length - 1;
        }    
        else if ( sign === 1){
    
            this.number = reverseString( string );
            this.length = string.length;
    
        }else{
    
            alert("The sign of the number is wrong!");
            // 程序停止
            // stop();
        }
        this.sign = sign;
    }
    
    // 字符串顛倒 (傳入字符串, 傳出字符串)
    function reverseString(string){
        return string.split("").reverse().join("");
    }
    
    // 補(bǔ)零 (傳入字符串, 傳出字符串)
    function addFrontZero( string , length ){
        for(let i = 0; i < length; i++){
            if(i > string.length - 1){
                string += "0";
            }
        }
        return string;
    }
    
    
    // 去零 (傳入字符串,傳出字符串)
    function deleteFrontZero( string ){
        
        let arr = string.split("");
    
        let end = arr.length - 1;
    
        while( arr[end--] === "0" ){
            arr.pop();
        }
    
        if(arr.length === 0){
            arr.push("0");
        }
        
        return arr.join("");
    }
    
    // 將參數(shù)統(tǒng)一轉(zhuǎn)換為字符串
    function numberTransform(number) {
    
        switch(typeof number){
            case "number":
                return String(number);
            case "object":
                return number.reverse().join("");
            case "undefined":
                alert("you didn"t input the number.");
            default:
                return number;
        }
    
    }
    
    // 分析元素
    function numberAnalysis( number ) {
    
        let raw = numberTransform( number );
        
        if( raw[0] != "-" && raw[0] < "0" || raw[0] >"9"){
            alert("The number you input is wrong.");
        }
    
        for(let i = 1; i < raw.length; i++){
            if(raw[i] < "0" || raw[0] > "9"){
                alert("The number you input is wrong.");
            }
        }
    
        if( raw[0] === "-" ){
            return new NumberObject( raw ,  -1);
        }else{
            return new NumberObject( raw , 1 );
        }
    
    }
    
    
    // 數(shù)字相加,(傳入字符串,傳出字符串)
    function addString( first, second ) {
    
        let carry = 0,
             rst = [];
        let length = first.length > second.length ? first.length : second.length;
        
        // 第一個加數(shù)
        let fst = addFrontZero(first, length);
        // 第二個加數(shù)
        let scd = addFrontZero(second, length);
    
        for(let i = 0; i < length || carry === 1; i++){
    
            if( fst[i] && scd[i] ){
    
                rst[i]   = ( (fst[i] - 0)  +  (scd[i] - 0)  + carry ) % 10;
                carry  = ( (fst[i] - 0)  +  (scd[i] - 0)  + carry ) / 10;
    
            }else if( !fst[i] && scd[i] ){
    
                rst[i]   = ( (scd[i] - 0) + carry ) % 10;
                carry  = ( (scd[i] - 0) + carry ) / 10;
    
            }else if( fst[i] && !scd[i] ){
    
                rst[i]   = ( (fst[i] - 0) + carry ) % 10;
                carry  = ( (fst[i] - 0) + carry ) / 10;
    
            }else if( !fst[i] && !scd[i] && carry === 1){
                
                rst[i]   = carry;
                carry  = 0;
            }else{
                alert("The logic of your addition is wrong.");
            }
    
            // JS 的商一般都為小數(shù),需要取整
            carry = Math.floor( carry );
        }
        return rst.join("");
    }
    
    function multiply( first , second ) {
        
        // 返回的字符串結(jié)果和判斷符號
        let firstNumber = first.number;
        let secondNumber = second.number;
    
    
        let rst = pieceOfMultiplication( firstNumber , secondNumber ).split("");
    
        // 判斷正負(fù)號
        if(first.sign * second.sign === -1){
            rst.push("-");
        }
    
        return new numberAnalysis( rst );
    
    }
    
    // 實現(xiàn)分治法
    function pieceOfMultiplication( first, second ) {
        
        let length = first.length > second.length ? first.length : second.length;
        
        // 補(bǔ)零,使得位數(shù)相同
        for(let i = 0; i < length; i++){
            if(i > first.length - 1){
                first.number += "0";
            }
            if(i > second.length - 1){
                second.number += "0";
            }
        }
    
        let half = Math.floor( length / 2 );
        
        // 分割數(shù)字
        let firstLeft = first.slice(0, half);
        let firstRight = first.slice( half );
        let secondLeft = second.slice(0, half);
        let secondRight = second.slice( half );
        
    
        // 遞歸長度大于2的數(shù)相乘
        if( half >= 2 ) {
            
            // 分解
            let leftRst = pieceOfMultiplication( firstLeft , secondLeft );
            let centerRst = addString( pieceOfMultiplication( firstLeft , secondRight ) , pieceOfMultiplication( firstRight , secondLeft ) );
            let rightRst = pieceOfMultiplication( firstRight , secondRight );
    
            leftRst = deleteFrontZero(String(leftRst));
            centerRst = deleteFrontZero(String(centerRst));
            rightRst = deleteFrontZero(String(rightRst));
    
    
            // 重組
            let left = leftRst.slice(0, half);
            let leftCarry = leftRst.slice(half);
    
    
            centerRst = addString(centerRst , leftCarry);
    
            let center = centerRst.slice(0, half);
            let centerCarry = centerRst.slice(half);
            
    
    
            let right = addString(rightRst , centerCarry);
    
    
            return deleteFrontZero(left + center + right);
    
        }
        // 兩位數(shù)相乘
        else if( half === 1) {
            // 一位或兩位的字符串轉(zhuǎn)數(shù)字
            let firstLeftNumber = Number(reverseString( firstLeft ));
            let firstRightNumber = Number(reverseString( firstRight ));
            let secondLeftNumber = Number(reverseString( secondLeft ));
            let secondRightNumber = Number(reverseString( secondRight ));
            
    
            // 相乘
            let leftRstNumber = firstLeftNumber * secondLeftNumber;
            let centerRstNumber = firstLeftNumber * secondRightNumber + secondLeftNumber * firstRightNumber;
            let rightRstNumber = firstRightNumber * secondRightNumber;
    
            
            // 重組
            let left = leftRstNumber % 10;
            let centerRst = Math.floor(leftRstNumber / 10) + centerRstNumber;
            let center = centerRst % 10;
            let right = Math.floor(centerRst / 10) + rightRstNumber;
    
    
            left = deleteFrontZero(reverseString( String(left) ));
            center = deleteFrontZero(reverseString( String(center) ));
            right = deleteFrontZero(reverseString( String(right) ));
            return deleteFrontZero( left + center + right );
    
        }
    
        else {
            alert("The multiplication is wrong");
        }
    
    }
    
    // 規(guī)定: 傳入的x 和 y 數(shù)據(jù)類型必須為字符型,因為大整數(shù)為默認(rèn)判定為數(shù)字上限
    function test(x, y) {
    
        let elem1 = numberAnalysis( x );
        let elem2 = numberAnalysis( y );
    
        let rst = multiply( elem1 , elem2 )
        
        if(rst.sign === -1){
            return "-" + reverseString( rst.number );
        }
        else if(rst.sign === 1){
            return reverseString( rst.number );
        }
    
    }

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/81759.html

相關(guān)文章

  • 思想

    摘要:基礎(chǔ)算法思想類別遞推枚舉遞歸分治貪婪回溯試探模擬遞推遞推分類順推法從已知條件出發(fā),逐步推算出要解決問題的方法。貪心算法的局限不能保證最后的解是最優(yōu)的不能求最大最小解問題只能求滿足某些約束條件的可行解范圍。 基礎(chǔ)算法思想類別 遞推 枚舉 遞歸 分治 貪婪 回溯(試探) 模擬 遞推 遞推分類 順推法:從已知條件出發(fā),逐步推算出要解決問題的方法。 逆推法:從已知結(jié)果出發(fā),用迭代表達(dá)式...

    sshe 評論0 收藏0
  • js入門(3)--遞歸

    摘要:在遞歸過程中,未完成計算的函數(shù)將會掛起壓入調(diào)用堆棧,不然遞歸結(jié)束的時候沒辦法進(jìn)行回溯。這就引出了回溯法回溯法就是在達(dá)到遞歸邊界前的某層,由于一些事實導(dǎo)致已經(jīng)不需要前往任何一個子問題遞歸,就可以直接返回上一層。 1簡介 遞歸在前端開發(fā)中應(yīng)用還是非常廣泛的,首先DOM就是樹狀結(jié)構(gòu),而這種結(jié)構(gòu)使用遞歸去遍歷是非常合適的。然后就是對象和數(shù)組的深復(fù)制很多庫也是使用遞歸實現(xiàn)的例如jquery中的e...

    jzman 評論0 收藏0
  • js 排序算之快速排序

    摘要:快速排序是一種劃分交換排序??焖倥判蚧诿芭葸f歸分治。他在大數(shù)據(jù)情況下是最快的排序算法之一,平均事件復(fù)雜度很低而且前面的系數(shù)很小,在大量隨機(jī)輸入的情況下最壞情況出現(xiàn)的概率是極小的。 快速排序是一種劃分交換排序。它采用了一種分治的策略,通常稱其為分治法。 分治法的基本思想是:將原問題分解為若干個規(guī)模更小但結(jié)構(gòu)與原問題相似的子問題。遞歸地解這些子問題,然后將這些子問題的解組合為原問題的解。...

    Eidesen 評論0 收藏0
  • 2018第九屆藍(lán)橋杯Java b組總結(jié)

    摘要:現(xiàn)在小明想統(tǒng)計有哪些帖子曾經(jīng)是熱帖。如果一個帖子曾在任意一個長度為的時間段內(nèi)收到不少于個贊,小明就認(rèn)為這個帖子曾是熱帖。以下行列代表一張海域照片。照片保證第行第列第行第列的像素都是海洋。 2018年4月1日愚人節(jié),我第一次參加了有關(guān)計算機(jī)算法類比賽藍(lán)橋杯,這篇算是經(jīng)驗總結(jié)和題目回顧,水平有限,有不妥之處歡迎留言批評指正,也可以加QQ891465170交流~下面進(jìn)入正題: 第一題:第幾...

    codecook 評論0 收藏0
  • 校招社招必備核心前端面試問題與詳細(xì)解答

    摘要:本文總結(jié)了前端老司機(jī)經(jīng)常問題的一些問題并結(jié)合個人總結(jié)給出了比較詳盡的答案。網(wǎng)易阿里騰訊校招社招必備知識點(diǎn)。此外還有網(wǎng)絡(luò)線程,定時器任務(wù)線程,文件系統(tǒng)處理線程等等。線程核心是引擎。主線程和工作線程之間的通知機(jī)制叫做事件循環(huán)。 showImg(https://segmentfault.com/img/bVbu4aB?w=300&h=208); 本文總結(jié)了前端老司機(jī)經(jīng)常問題的一些問題并結(jié)合個...

    DevTalking 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<