JavaScript 四則運算:加減乘除


這幾天也在學習 javascript,前幾日看了一篇關於解析四則運算表達式和算法的文章,覺得四則運算很常用,打算編寫代碼看看最終結果。

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

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

 

分析了作者寫的代碼后,在此基礎上加了些代碼。在這個過程中鞏固學習了關於堆棧的知識以及棧(后進先出)和隊列(先進先出)方法。

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

 

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

 1         function isOperator(value) {
 2             var operatorString = "+-*/()";
 3             return operatorString.indexOf(value) > -1
 4         }
 5 
 6         function getPrioraty(value) {
 7             switch (value) {
 8                 case '+':
 9                 case '-':
10                     return 1;
11                 case '*':
12                 case '/':
13                     return 2;
14                 default:
15                     return 0;
16             }
17         }
18 
19         //判斷加減乘除的優先級
20         function prioraty(o1, o2) {  
21             return getPrioraty(o1) <= getPrioraty(o2);
22         }

 

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

 1         function dal2Rpn(exp) {
 2             //輸入棧
 3             var inputStack = [];
 4             //輸出棧
 5             var outputStack = [];
 6             //輸出隊列
 7             var outputQueue = [];
 8 
 9             for (var i = 0, len = exp.length; i < len; i++) {
10                 var cur = exp[i];
11                 if (cur != ' ') {
12                     inputStack.push(cur); //+-*/() 數字,逐個添加到末尾
13                 }
14             }
15 
16             //處理字符和數字
17             while (inputStack.length > 0) {
18 
19                 //shift 頂部取得一項后移除,unshift 頂部推入
20                 cur = inputStack.shift();
21 
22                 //如果是符號 -->  + - * / ( )
23                 if (isOperator(cur)) {
24                     if (cur == '(') {
25                         //push 從尾部推入一項
26                         outputStack.push(cur);
27                     } else if (cur == ')') {
28                         //pop 從尾部取得一項,之后移出
29                         var po = outputStack.pop();
30                         while (po != '(' && outputStack.length > 0) {
31                             outputQueue.push(po);
32                             po = outputStack.pop();
33                         }
34                         if (po != '(') {
35                             throw "錯誤:沒有匹配";
36                         }
37                     } else { //符號時,處理 + - * /
38                         while (prioraty(cur, outputStack[outputStack.length - 1])
39                                 && outputStack.length > 0) {
40                             outputQueue.push(outputStack.pop());
41                         }
42                         outputStack.push(cur);
43                     }
44                 } else { //是數字的時候,推入數字
45                     outputQueue.push(new Number(cur));
46                 }
47             }
48 
49             if (outputStack.length > 0) {
50                 if (outputStack[outputStack.length - 1] == ')'
51                         || outputStack[outputStack.length - 1] == '(') {
52                     throw "錯誤:沒有匹配";
53                 }
54                 while (outputStack.length > 0) {
55                     outputQueue.push(outputStack.pop());
56                 }
57             }
58             return evalRpn(outputQueue);
59         }

 

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

 1         function evalRpn(queue) { 
 2             var outputStack = [];
 3             while (queue.length > 0) {
 4                 var cur = queue.shift();
 5 
 6                 if (!isOperator(cur)) {
 7                     outputStack.push(cur);
 8                 } else {
 9                     //如果輸出堆棧長度小於 2
10                     if (outputStack.length < 2) {
11                         throw "無效堆棧長度";
12                     }
13                     var second = outputStack.pop();
14                     var first = outputStack.pop();
15 
16                     outputStack.push(getResult(first, second, cur));
17                 }
18             }
19 
20             if (outputStack.length != 1) {
21                 throw "不正確的運算";
22             } else {
23                 return outputStack[0];
24             }
25         }

 

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

 1         function getResult(first, second, operator){
 2             var result = 0;
 3             switch (operator) {
 4                 case '+':
 5                     result = first + second;
 6                     break;
 7                 case '-':
 8                     result = first - second;
 9                     break;
10                 case '*':
11                     result = first * second;
12                     break;
13                 case '/':
14                     result = first / second;
15                     break;
16                 default:
17                     return 0;
18             }
19 
20             //浮點數的小數位超過兩位時,只保留兩位小數點
21             function formatFloat(f, digit) {
22                 //pow(10,n) 為 10 的 n 次方
23                 var m = Math.pow(10, digit);
24                 return parseInt(f * m, 10) / m;
25             }
26             return (formatFloat(result, 2));
27         }

 

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

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

 


免責聲明!

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



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