赞
踩
给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。
整数除法仅保留整数部分。
你可以假设给定的表达式总是有效的。所有中间结果将在 [-231, 231 - 1] 的范围内。
注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval() 。
示例 1:
输入:s = “3+2*2” 输出:7 示例 2:
输入:s = " 3/2 " 输出:1 示例 3:
输入:s = " 3+5 / 2 " 输出:5
public int calculate(String s) { //优先级Map HashMap<Character, Integer> prio = new HashMap<>(); prio.put('+', 2); prio.put('-', 2); prio.put('*', 3); prio.put('/', 3); //存放解析的数字 Stack<Integer> stk = new Stack<>(); //存放操作符 Stack<Character> ops = new Stack<>(); //由整数和算符 ('+', '-', '*', '/') 组成,中间由一些空格隔开 过滤空格 s = s.replace(" ", ""); int length = s.length(); for (int i = 0; i < length;) { // 依次获取字符 char c = s.charAt(i); if (Character.isDigit(c)) { // 属于数字逻辑 int num = 0; while (i < length && Character.isDigit(s.charAt(i))) { num = num * 10 + s.charAt(i) - '0'; i++; } //存放数字 stk.push(num); } else { //属于('+', '-', '*', '/') while (!ops.isEmpty() && prio.get(c) <= prio.get(ops.peek())) { /** 判断优先级由于我们使用栈存放数字和操作符(先进后出) 举个例子: 1-1-3 假如没有优先级:先算1-3 = -2 然后 -2 进栈,最后 1-(-2) = 3 有优先级控制,当第二个‘-’号判断的时候会和ops.peek() 做比较一样就进来做计算。 1-1*3 这个就不需要进来因为本来就是先算1*3 **/ calculateBase(ops, stk); } //存放当前操作符 ops.push(c); i++; } } while (!ops.isEmpty()) { //最后计算里面剩余的逻辑比如:3+2*2 (本题最多两个操作符)1-1-3 由于上面优先级判断的时候计算过一轮 最后只有两个数字一个操作符 calculateBase(ops, stk); } return stk.peek(); } /** * 加减乘除基础计算结果入栈 * @param ops * @param stk */ private static void calculateBase(Stack<Character> ops, Stack<Integer> stk) { if (ops.isEmpty() || stk.size() < 2) { return; } char op = ops.pop(); int r = stk.pop(); int l = stk.pop(); int res = 0; if (op == '*') { res = l * r; } if (op == '/') { res = l / r; } if (op == '+') { res = l + r; } if (op == '-') { res = l - r; } stk.push(res); }
给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。
注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval() 。
示例 1:
输入:s = “1 * 1 + 1/1+(1-1)” 输出:2 示例 2:
输入:s = " 2-1 + 2 " 输出:3 示例 3:
输入:s = “(1+(4+5+2)-3)+(6+8)” 输出:23
public int calculate(String s) { //优先级Map HashMap<Character, Integer> prio = new HashMap<>(); prio.put('(', 1); prio.put('+', 2); prio.put('-', 2); prio.put('*', 3); prio.put('/', 3); //过滤空格、特殊表达式替换(-2)替换成(0-2)、(+2)替换成(0+2)方便统一计算 s = s.replace(" ", "").replace("(-", "(0-").replace("(+", "(0+"); //获取替换后字符串长度 int length = s.length(); //存放解析的数字 Stack<Integer> stk = new Stack<>(); //存放操作符 Stack<Character> ops = new Stack<>(); for (int i = 0; i < length; ) { // 依次获取字符 char c = s.charAt(i); if (Character.isDigit(c)) { // 属于数字逻辑 int num = 0; //判断是否存在连续的数字eg:1234+3 1234就得通过下面逻辑处理 while (i < length && Character.isDigit(s.charAt(i))) { num = num * 10 + (s.charAt(i) - '0'); i++; } //存放数字 stack.push(num); } else if (c == '(') { //遇到左括号入栈 因为需要判断和右括号对应 op.push(c); i++; } else if (c == ')') { //遇到右括号,判断是否需要计算 while (i < length && !op.isEmpty() && op.peek() != '(') { calculateBase(op, stack); } //出栈对应的左括号 if (!op.isEmpty()) { op.pop(); } i++; } else { //属于('+', '-', '*', '/') while (!op.isEmpty() && prio.get(c) <= prio.get(op.peek())) { /** 判断优先级由于我们使用栈存放数字和操作符(先进后出) 举个例子: 1-1-3 假如没有优先级:先算1-3 = -2 然后 -2 进栈,最后 1-(-2) = 3 有优先级控制,当第二个‘-’号判断的时候会和ops.peek() 做比较一样就进来做计算。 1-1*3 这个就不需要进来因为本来就是先算1*3 **/ calculateBase(op, stack); } //处理-() if (stack.isEmpty()) { stack.push(0); } op.push(c); i++; } } while (!op.isEmpty()) { //最后计算里面剩余的逻辑比如:3+2*2 (本题最多两个操作符)1-1-3 由于上面优先级判断的时候计算过一轮 最后只有两个数字一个操作符 calculateBase(op, stack); } return stack.peek(); } private static void calculateBase(Stack<Character> ops, Stack<Integer> stk) { if (ops.isEmpty() || stk.size() < 2) { return; } char op = ops.pop(); int r = stk.pop(); int l = stk.pop(); int res = 0; if (op == '*') { res = l * r; } if (op == '/') { res = l / r; } if (op == '+') { res = l + r; } if (op == '-') { res = l - r; } stk.push(res); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。