题目描述
实现一个计算器支持+、-、*、/、(、)等,需要支持括号嵌套。
示例 1:
1 2
| 输入:s = 1*2-3*5*8/4+3 输出:-25
|
示例 2:
1 2
| 输入:s = 12*4-25+6/(2+(2-1)*2-1)-4*3 输出:13
|
示例 3:
1 2
| 输入:s = 12*4-(25+6/(2+(2-1)*2-1)-4*3) 输出:33
|
示例 4:
1 2
| 输入:s = 12*4/2-(25+6/(2+(2-1)*2-1)-4*3) 输出:9
|
我的解法
思路
此题与leetcode题库中的 面试题 16.26. 计算器 非常类似,不同的是此题需要处理嵌套的括号。一个比较普遍的思路就是首先处理括号,将整个表达式转换为没有括号的算式,再进行计算。
我们使用栈记录已经遍历的字符,当遇到第一个右括号时,说明是第一个嵌套最深的括号,我们依次弹出元素,直到遇到与其匹配的左括号,计算后,再次压入栈中。重复以上步骤,便可处理掉所有括号,接下来再计算算式。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| class Solution {
public int calculate(String s) { LinkedList<String> s1 = new LinkedList<>(); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (c != ')') { s1.addLast(String.valueOf(c)); continue; } StringBuilder sb = new StringBuilder(); while (!s1.isEmpty() && !"(".equals(s1.getLast())) { sb.append(s1.removeLast()); } s1.removeLast(); s1.addLast(String.valueOf(calculateNormal(sb.reverse().toString()))); } StringBuilder sb = new StringBuilder(); s1.forEach(sb::append); return calculateNormal(sb.toString()); }
private int calculateNormal(String s) { int num = 0; char preSign = '+'; LinkedList<Integer> stack = new LinkedList<>(); for (int i = 0; i < s.length(); ++i) { boolean digit = Character.isDigit(s.charAt(i)); if (digit) { num = num * 10 + s.charAt(i) - '0'; } if (!digit || i == s.length() - 1) { switch (preSign) { case '+': stack.push(num); break; case '-': stack.push(-num); break; case '*': stack.push(stack.pop() * num); break; default: stack.push(stack.pop() / num); } preSign = s.charAt(i); num = 0; } } return (int) stack.stream().mapToInt(x -> x).summaryStatistics().getSum(); }
}
|
测试
添加测试用例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class Test { String S; int Expect;
public Test(String s, int expect) { this.S = s; this.Expect = expect; } }
public class Main {
public static void main(String[] args) { Solution solution = new Solution(); Test[] testList = new Test[]{ new Test("1*2-3*5*8/4+3", 1 * 2 - 3 * 5 * 8 / 4 + 3), new Test("12*4-25+6/(2+(2-1)*2-1)-4*3", 12 * 4 - 25 + 6 / (2 + (2 - 1) * 2 - 1) - 4 * 3), new Test("12*4-(25+6/(2+(2-1)*2-1)-4*3)", 12 * 4 - (25 + 6 / (2 + (2 - 1) * 2 - 1) - 4 * 3)), new Test("12*4/2-(25+6/(2+(2-1)*2-1)-4*3)", 12 * 4 / 2 - (25 + 6 / (2 + (2 - 1) * 2 - 1) - 4 * 3)), }; for (Test test : testList) { int calculate = solution.calculate(test.S); System.out.println((calculate == test.Expect) + "------>" + calculate); } }
}
|
运行启动类,查看控制台:
1 2 3 4
| true------>-25 true------>13 true------>33 true------>9
|