Calculator.java 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import java.util.Scanner;
  2. import java.util.Stack;
  3. public class Calculator {
  4. public static void main(String[] args) {
  5. try (Scanner sc = new Scanner(System.in)) {
  6. String str = sc.nextLine();
  7. System.out.println(calculate(str));
  8. } catch (Exception e) {
  9. e.printStackTrace();
  10. }
  11. }
  12. private static double calculate(String str) throws Exception {
  13. char[] exp = str.toCharArray();
  14. Stack<Character> ops = new Stack<>();
  15. Stack<Double> num = new Stack<>();
  16. // + - * / ( ) $
  17. // + > > < < < > >
  18. // - > > < < < > >
  19. // * > > > > < > >
  20. // / > > > > < > >
  21. // ( < < < < < =
  22. // E < < < < < ac
  23. for (int i = 0; i <= exp.length;) {
  24. if (i == exp.length) {
  25. if (ops.isEmpty()) break;
  26. if (ops.peek() == '(') throw new Exception("Invalid expression!");
  27. operate(ops, num);
  28. continue;
  29. }
  30. switch (exp[i]) {
  31. case '+': case '-':
  32. if (ops.isEmpty() || ops.peek() == '(') {
  33. ops.push(exp[i++]);
  34. } else {
  35. operate(ops, num);
  36. }
  37. break;
  38. case '*': case '/':
  39. if (ops.isEmpty() || ops.peek() == '(' || ops.peek() == '+' || ops.peek() == '-') {
  40. ops.push(exp[i++]);
  41. } else {
  42. operate(ops, num);
  43. }
  44. break;
  45. case '(':
  46. ops.push(exp[i++]);
  47. break;
  48. case ')':
  49. if (ops.isEmpty()) throw new Exception("Invalid expression!");
  50. if (ops.peek() == '(') {
  51. ops.pop();
  52. i++;
  53. } else {
  54. operate(ops, num);
  55. }
  56. break;
  57. default:
  58. int j;
  59. for (j = i + 1; j < exp.length && (('0' <= exp[j] && exp[j] <= '9') || exp[j] == '.'); j++);
  60. double n = Double.parseDouble(str.substring(i, j));
  61. num.push(n);
  62. i = j;
  63. }
  64. }
  65. if (num.size() != 1) throw new Exception("Invalid expression!");
  66. return num.peek();
  67. }
  68. private static void operate(Stack<Character> ops, Stack<Double> num) throws Exception {
  69. if (num.size() < 2) throw new Exception("Invalid expression!");
  70. char op = ops.pop();
  71. double n2 = num.pop(), n1 = num.pop();
  72. switch (op) {
  73. case '+':
  74. num.push(n1 + n2);
  75. break;
  76. case '-':
  77. num.push(n1 - n2);
  78. break;
  79. case '*':
  80. num.push(n1 * n2);
  81. break;
  82. case '/':
  83. if (n2 == 0.0) throw new Exception("Divided by 0!");
  84. num.push(n1 / n2);
  85. break;
  86. }
  87. }
  88. }