[LeetCode][JavaScript]Basic Calculator II

Basic Calculator II

Implement a basic calculator to evaluate a simple expression string.

The expression string contains only non-negative integers, +, -, *, and / operators. The integer division should truncate toward zero.

You may assume that the given expression is always valid.

Some examples:

"3+2*2" = 7
" 3/2 " = 1
" 3+5 / 2 " = 5

Note: Do not use the eval built-in library function.

https://leetcode.com/problems/basic-calculator-ii/

 

 


 

 

接着上一题,符号括充到+-*/(),http://www.cnblogs.com/Liok3187/p/4564877.html

增加了一个方法getPerority用来定义各个符号的优先级。

乘除法比加减法优先级高,判断条件就是当前输入符号的优先级小于等于opStack栈顶符号优先级的时候可以做压缩操作,好长的一句话。

详细的过程要看一下后缀表达式,这里简单地举一下混合运算的栗子:

1+2*3

这时两个栈的状态为resultStack : [1,2,3], opStack : [+,*]

此时再输入一个/,拿/和栈顶的*比,getPerority(/) --> 1 小于等于 getPerority(*) --> 1,优先级相同。

发现可以做乘法的运算(压缩),运算后两个栈的状态为resultStack : [1,6], opStack : [+]

这时getPerority(/) --> 2 大于 getPerority(+) --> 1, 判断不能再压缩了,最后结果:resultStack : [1,6], opStack : [+,/]

 

还是刚才的栗子

1+2*3

resultStack : [1,2,3], opStack : [+,*],这一次输入-。

拿-和栈顶的*比,getPerority(-) --> 1 小于等于 getPerority(*) --> 1,压缩,结果为resultStack : [1,6], opStack : [+]

此时getPerority(-) --> 1 小于等于 getPerority(+) --> 1,仍旧可以做,最后结果:resultStack : [7], opStack : [-]

 

再考虑上括号的情况,我把括号的优先级设成了0,也就是比四则运算都要低。

因为如果做二元压缩运算碰到括号的话,肯定是要跳出的,因为只有碰到右括号的时候才能成对地做括号的压缩。

 

当读完所有的字符串之后,opStack可能还有剩下没有压缩的符号,注意到这时opStack里不可能有括号了,如果有就是输入的格式不对,这题默认输入是合法的。

能看到有compress_2operators('#'),什么符号都可以,代表结束,getPerority('#')返回-1,优先级最小,压缩所有opStack里剩下的符号。

 1 /**
 2  * @param {string} s
 3  * @return {number}
 4  */
 5 var calculate = function(s) {
 6     var resultStack = [];
 7     var opStack = [];
 8     var temp = "";
 9     for(var i = 0; i < s.length; i++){
10         var ch = s[i];
11         if(/^(\+|\-)$/.test(ch)){ // + -
12             compress_2operators(ch);
13             opStack.push(ch);
14         }else if(/^(\/|\*)$/.test(ch)){
15             compress_2operators(ch);
16             opStack.push(ch);
17         }else if(ch === '('){
18             opStack.push(ch);
19         }else if(ch === ')'){
20             compress_bracket();
21         }else if(/^[0-9]$/.test(ch)){
22             temp += ch;
23         }
24 
25         if(s[i + 1] && /^(\+|\-|\(|\)|\/|\*)$/.test(s[i + 1])){ // + - * / ( )
26             if(temp !== ""){
27                 resultStack.push(parseInt(temp));
28                 temp = "";
29             }
30         }
31     }
32     if(temp !== ""){
33         resultStack.push(parseInt(temp));
34         temp = "";
35     }
36     compress_2operators('#');
37     return resultStack.pop();
38 
39     function getPerority(ch){
40         if(ch === '('){
41             return 0;
42         }else if(/^(\+|\-)$/.test(ch)){
43             return 1;
44         }else if(/^(\/|\*)$/.test(ch)){
45             return 2;
46         }
47         return -1;
48     }
49     function compress_bracket(){
50         while(opStack[opStack.length - 1] !== '('){
51             compress_2operators('(');
52         }
53         opStack.pop(); //(
54     }
55     function compress_2operators(ch){
56         var perority = getPerority(ch);
57         while(/^(\+|\-|\/|\*)$/.test(opStack[opStack.length - 1])){ // + - * /
58             var top = opStack[opStack.length - 1];
59             if(perority <= getPerority(top)){
60                 var op = opStack.pop();
61                 var right = resultStack.pop();
62                 var left = resultStack.pop();
63                 if(op === '+'){
64                     resultStack.push(left + right);
65                 }else if(op === '-'){
66                     resultStack.push(left - right);
67                 }else if(op === '/'){
68                     resultStack.push(parseInt(left / right));
69                 }else if(op === '*'){
70                     resultStack.push(left * right);
71                 }
72             }else{
73                 return;
74             }
75         }
76     }
77 };

 

 

 

posted @ 2015-06-22 15:37  `Liok  阅读(398)  评论(0编辑  收藏  举报