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);   //输出结果

 

你可能感兴趣的:(JavaScript)