227. 基本计算器 II

  1. class Solution {
  2. public int calculate(String s) {
  3. // 预处理
  4. s = s.replace(" ", "");
  5. s = s.replace("(-", "(0-");
  6. Deque<Integer> num = new LinkedList<>();
  7. num.push(0);
  8. Deque<Character> ch = new LinkedList<>();
  9. int index = 0;
  10. while (index < s.length()) {
  11. char cur = s.charAt(index);
  12. if (cur == '(') {
  13. ch.push(cur);
  14. } else if (cur == ')') {
  15. // 计算直到遇到左边的'('
  16. while (ch.peek() != '(') {
  17. cal(num, ch);
  18. }
  19. // 弹出左边的'('
  20. ch.pop();
  21. } else if (cur == '+' || cur == '-' || cur == '*' || cur =='/') {
  22. while (!ch.isEmpty() && ch.peek() != '(') {
  23. // 将优先级高的全部进行计算
  24. char pre = ch.peek();
  25. if (compare(pre, cur)) {
  26. // pre的优先级高
  27. cal(num, ch);
  28. } else {
  29. break;
  30. }
  31. }
  32. ch.push(cur);
  33. } else {
  34. int curNum = 0;
  35. while (index < s.length() && Character.isDigit(s.charAt(index))) {
  36. curNum = 10 * curNum + (s.charAt(index) - '0');
  37. ++index;
  38. }
  39. num.push(curNum);
  40. continue;
  41. }
  42. ++index;
  43. }
  44. while (!ch.isEmpty()) {
  45. cal(num, ch);
  46. }
  47. return num.peek();
  48. }
  49. private boolean compare(char pre, char opt) {
  50. if (pre == '*' || pre == '/')
  51. return true;
  52. if ((pre == '+' || pre == '-') && (opt == '-' || opt == '+'))
  53. return true;
  54. return false;
  55. }
  56. private void cal(Deque<Integer> num, Deque<Character> ch) {
  57. int num1 = num.pop();
  58. int num2 = num.pop();
  59. if (ch.peek() == '+') {
  60. num.push(num1 + num2);
  61. } else if (ch.peek() == '*') {
  62. num.push(num1 * num2);
  63. } else if (ch.peek() == '/') {
  64. num.push(num2 / num1);
  65. }else {
  66. num.push(num2 - num1);
  67. }
  68. ch.pop();
  69. }
  70. }