zoukankan      html  css  js  c++  java
  • [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 };
  • 相关阅读:
    树的子结构(剑指offer_26)
    合并两个排序的链表(剑指offer_25)
    反转链表(剑指offer_24)多看多思多想
    链表中环的入口结点(剑指offer_23)
    链表中倒数第k个节点
    调整数组顺序使奇数位于偶数前面(剑指offer_21)
    表示数值的字符串(剑指offer_20)
    1676. 跳石头
    1670. 回合制游戏
    1667. 区间统计(回顾)
  • 原文地址:https://www.cnblogs.com/Liok3187/p/4593365.html
Copyright © 2011-2022 走看看