题解 | #表达式求值#

表达式求值

https://www.nowcoder.com/practice/c215ba61c8b1443b996351df929dc4d4

import java.util.*;

/**
  双栈直接求解,核心思想是:先把运算符优先级高的两侧的数字算出,先把优先级高的运算符入栈,
  下次遇到优先级低的运算符时,就计算该运算符前面的优先级较高的运算符两侧的数字
 */
public class Solution {

  /**计算运算符的优先级 */
  boolean grade(char op1, char op2) {//比较当前运算符(op1)和栈顶运算符(op2)的优先级
    if (op1 == '*') return true;
    if (op2 == '*') return false;
    if (op1 == '-' && op2 == '-') return false;
    return true;
  }
  /**计算数值 */
  int calc(Stack<Integer> nums, char op) {
    int result = 0;
    if (nums.size() >= 2) {//当数字栈中的元素大于2时的计算方式
      int a = nums.pop();
      int b = nums.pop();
      switch (op) {
        case '+':
          result = b + a;
          break;
        case '-':
          result = b - a;
          break;
        case '*':
          result = b * a;
          break;
      }
    } else {//当数字栈中只有一个元素时,此时操作符栈中的元素为'+'或'-',处理当测试用例为"-1"或"+1"的情况
      result = nums.pop();
      if (op == '-') result = -result;
    }
    return result;
  }
  /**判断是否为数字 */
  boolean isNum(char c) {
    if (c - '0' >= 0 && c - '0' <= 9) return true;
    return false;
  }
  /**
   * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
   * 返回表达式的值
   * @param s string字符串 待计算的表达式
   * @return int整型
   */
  Stack<Integer> nums = new Stack<>();
  Stack<Character> ops = new Stack<>();

  public int solve (String s) {
    int result = 0;
    int flag = 0;//记录是否连续读入了多个数字字符,处理输入为:"12+100"的情况
    // write code here
    for (int i = 0; i < s.length(); i++) {
      if (isNum(s.charAt(i))) {//当前字符是数字,则加入数字栈中
        if (flag == 1) {//第二至多次遇到数字字符
          int temp = nums.pop() * 10;
          nums.push(temp + (s.charAt(i) - '0'));
        } else {//第一次遇到数字字符
          nums.push(s.charAt(i) - '0');
          flag = 1;
        }
      } else if (s.charAt(i) == '(') {//遇到左括号,直接压入操作符栈
        flag = 0;//表示当前字符为运算符
        ops.push(s.charAt(i));
      } else if (s.charAt(i) == ')') {//遇到右括号,需要将该右括号前的表达式算出
        flag = 0;
        while (ops.peek() != '(') {//凡是加入运算符栈的字符,这样的表达式都满足后缀表达式,因此按照出栈顺序就可算出
          nums.push(calc(nums, ops.pop()));
        }
        ops.pop();//将左括号弹出
      } else if (ops.isEmpty() || grade(s.charAt(i), ops.peek())) {//优先级高的运算符入栈
        flag = 0;
        ops.push(s.charAt(i));
      } else {//遇到优先级低的运算符,需要将该运算符前面的优先级高的运算符所表示的表达式计算出来
        flag = 0;
        while (!grade(s.charAt(i), ops.peek())) {
          nums.push(calc(nums, ops.pop()));
          if (ops.size() == 0) break;//有可能最后一个运算符出栈后,栈就空了,再去判断循环条件时,会出现空栈异常
        }
        ops.push(s.charAt(i));//优先级低的运算符入栈
      }
    }
	//以上循环结束后,运算符栈中只有'+'或'-'了,直接按后缀表达式计算计算即可
    while (!ops.isEmpty()) {
      nums.push(calc(nums, ops.pop()));
    }
    return nums.peek();
  }

}

全部评论

相关推荐

抱抱碍事梨a:三点建议,第一点是建议再做一个项目,把自我介绍部分顶了,第二点是中南大学加黑加粗,第三点是建议加v详细交流
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
06-05 15:27
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务