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 };