JavaScript 四則運算:加減乘除

來源:互聯網
上載者:User

這幾天也在學習 javascript,前幾日師傅給了一篇關於解析四則運算運算式和演算法的文章,說四則運算很常用讓我好好看看,再讓編寫代碼看看最終結果。

首先我看了代碼瞭解了兩個關於算術或邏輯公式的標記法:中綴標記法以及逆波蘭標記法,也學習了四則運算的實際轉換過程(此定義在原文有詳細解釋)。

原文:http://www.jb51.net/article/53537.htm

 

然後我看了作者寫的代碼,自己分析看明白後,再加了些代碼。在這個過程中鞏固學習了關於堆棧的知識以及棧(後進先出)和隊列(先進先出)方法。

以下代碼就是自認為比較完整的代碼:

 

首先判斷加減乘除的優先順序,* 和 / 的優先順序高於 + 和 - :

function isOperator(value) {
            var operatorString = "+-*/()";
            return operatorString.indexOf(value) > -1
        }

        function getPrioraty(value) {
            switch (value) {
                case '+':
                case '-':
                    return 1;
                case '*':
                case '/':
                    return 2;
                default:
                    return 0;
            }
        }

        //判斷加減乘除的優先順序
        function prioraty(o1, o2) { 
            return getPrioraty(o1) <= getPrioraty(o2);
        }

定義輸入、輸出棧以及輸出隊列,迴圈逐個添加到輸入棧的末尾,之後處理符號和數字,當找到 "(" 和 ")" 時特殊處理:

function dal2Rpn(exp) {
            //輸入棧
            var inputStack = [];
            //輸出棧
            var outputStack = [];
            //輸出隊列
            var outputQueue = [];

            for (var i = 0, len = exp.length; i < len; i++) {
                var cur = exp[i];
                if (cur != ' ') {
                    inputStack.push(cur); //+-*/() 數字,逐個添加到末尾
                }
            }

            //處理字元和數字
            while (inputStack.length > 0) {

                //shift 頂部取得一項後移除,unshift 頂部推入
                cur = inputStack.shift();

                //如果是符號 -->  + - * / ( )
                if (isOperator(cur)) {
                    if (cur == '(') {
                        //push 從尾部推入一項
                        outputStack.push(cur);
                    } else if (cur == ')') {
                        //pop 從尾部取得一項,之後移出
                        var po = outputStack.pop();
                        while (po != '(' && outputStack.length > 0) {
                            outputQueue.push(po);
                            po = outputStack.pop();
                        }
                        if (po != '(') {
                            throw "錯誤:沒有匹配";
                        }
                    } else { //符號時,處理 + - * /
                        while (prioraty(cur, outputStack[outputStack.length - 1])
                                && outputStack.length > 0) {
                            outputQueue.push(outputStack.pop());
                        }
                        outputStack.push(cur);
                    }
                } else { //是數位時候,推入數字
                    outputQueue.push(new Number(cur));
                }
            }

            if (outputStack.length > 0) {
                if (outputStack[outputStack.length - 1] == ')'
                        outputStack[outputStack.length - 1] == '(') {
                    throw "錯誤:沒有匹配";
                }
                while (outputStack.length > 0) {
                    outputQueue.push(outputStack.pop());
                }
            }
            return evalRpn(outputQueue);
        }

定義 evalRpn() 函數,輸出堆棧的長度不小於2的時候,進行計算:

function evalRpn(queue) { 
            var outputStack = [];
            while (queue.length > 0) {
                var cur = queue.shift();

                if (!isOperator(cur)) {
                    outputStack.push(cur);
                } else {
                    //如果輸出堆棧長度小於 2
                    if (outputStack.length < 2) {
                        throw "無效堆棧長度";
                    }
                    var second = outputStack.pop();
                    var first = outputStack.pop();

                    outputStack.push(getResult(first, second, cur));
                }
            }

            if (outputStack.length != 1) {
                throw "不正確的運算";
            } else {
                return outputStack[0];
            }
        }

進行加減乘除計算之後,對其值進行操作,當浮點數的小數位超過兩位時,只保留兩位小數點:

function getResult(first, second, operator){
            var result = 0;
            switch (operator) {
                case '+':
                    result = first + second;
                    break;
                case '-':
                    result = first - second;
                    break;
                case '*':
                    result = first * second;
                    break;
                case '/':
                    result = first / second;
                    break;
                default:
                    return 0;
            }

            //浮點數的小數位超過兩位時,只保留兩位小數點
            function formatFloat(f, digit) {
                //pow(10,n) 為 10 的 n 次方
                var m = Math.pow(10, digit);
                return parseInt(f * m, 10) / m;
            }
            return (formatFloat(result, 2));
        }

輸入要計算的運算式,計算結果 ( 結果得到 -0.6 ):

var result=dal2Rpn('( 1 + 2 ) * (( 3 - 4 ) / 5)');
 console.log(result);   //輸出結果



相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.