-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathEvaluateMathematicalExpression.java
103 lines (92 loc) · 4.44 KB
/
EvaluateMathematicalExpression.java
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package katas.java;
import java.util.List;
import java.util.Stack;
import java.util.stream.Collectors;
/**
* @author JDev
* <p>
* Kata: https://www.codewars.com/kata/517abf86da9663f1d2000003
*/
public class EvaluateMathematicalExpression {
public static void main(String[] args) {
System.out.printf("%-30s %-10.4f\n", "3 - -( -3) = ", calculate("3 - -( -3)")); //0
// System.out.printf("%-30s %-10.4f\n", "1 - -(-(-(-4))) = ", calculate("1 - -(-(-(-4)))")); //0
// System.out.printf("%-30s %-10.4f\n", "((80 - (19))) = ", calculate("((80 - (19)))")); //61
// System.out.printf("%-30s %-10.4f\n", "3 - -3 = ", calculate("3 - -3")); //6
// System.out.printf("%-30s %-10.4f\n", "-123 = ", calculate("-123"));
// System.out.printf("%-30s %-10.4f\n", "2 /2+3 * 4.75- -6 = ", calculate("2 /2+3 * 4.75- -6")); //21.25
// System.out.printf("%-30s %-10.4f\n", "2 / (2 + 3) * 4.33 - -6 = ", calculate("2 / (2 + 3) * 4.33 - -6")); //7.732
// System.out.printf("%-30s %-10.4f\n", "12* 123 = ", calculate("12* 123")); //1476
// System.out.printf("%-30s %-10.4f\n", "3 + 4 * 2 / ( 1 - ((55)) ) = ", calculate("3 + 4 * 2 / ( 1 - ((55)) )")); //8.851
// System.out.printf("%-30s %-10.4f\n", "1-1 = ", calculate("1-1")); //0
// System.out.printf("%-30s %-10.4f\n", "1 - -1 = ", calculate("1 - -1")); //2
}
private static double calculate(String expression) {
Stack<Double> vStack = new Stack<Double>();
Stack<Character> oStack = new Stack<Character>();
List<Character> chars = expression.replaceAll("\\s", "").chars().mapToObj(c -> Character.valueOf((char) c)).collect(Collectors.toList());
for (int i = 0; i < chars.size(); i++) {
// if (chars.get(i) == ' ')
// continue;
if (isDigit(chars, i) || isNegativeNumber(chars, i)) {
String buffer = "";
while (i < chars.size() && (isDigit(chars, i) || isNegativeNumber(chars, i)))
buffer += chars.get(i++);
vStack.push(Double.valueOf(buffer));
i--;
} else if (chars.get(i) == '(') {
oStack.push(chars.get(i));
} else if (chars.get(i) == ')') {
while (oStack.peek() != '(')
vStack.push(applyOperation(oStack.pop(), vStack.pop(), vStack.pop()));
oStack.pop();
} else if (chars.get(i).toString().matches("[\\+\\-\\*\\/]")) {
// if (!isNegativeNumber(chars, i)) {
while (!oStack.empty() && hasPrecedence(chars.get(i), oStack.peek()))
vStack.push(applyOperation(oStack.pop(), vStack.pop(), vStack.pop()));
oStack.push(chars.get(i));
// }
}
}
while (!oStack.empty())
vStack.push(applyOperation(oStack.pop(), vStack.pop(), vStack.pop()));
return vStack.pop().doubleValue();
}
private static boolean isDigit(List<Character> chars, int index) {
return Character.isDigit(chars.get(index)) || chars.get(index) == '.';
}
private static boolean isNegativeNumber(List<Character> chars, int index) {
if (index == 0 && chars.get(index) == '-') {
return true;
} else if (!Character.isDigit(chars.get(index - 1)) && chars.get(index) == '-' && Character.isDigit(chars.get(index + 1))) {
return true;
// } else if (chars.get(index) == '-' && Character.isDigit(chars.get(index + 1))) {
// return true;
} else if (chars.get(index) == '-' && chars.get(index + 1) == '-' && index < chars.size() && Character.isDigit(chars.get(index + 2))) {
return false;
}
return false;
// return (index == 0 || chars.get(index - 1) == ' ') && chars.get(index) == '-' && Character.isDigit(chars.get(index + 1));
}
private static boolean hasPrecedence(char lOp, char rOp) {
if (rOp == '(' || rOp == ')')
return false;
if ((lOp == '*' || lOp == '/') && (rOp == '+' || rOp == '-'))
return false;
else
return true;
}
private static double applyOperation(Character o, double r, double l) {
switch (o) {
case '-':
return l - r;
case '+':
return l + r;
case '*':
return l * r;
case '/':
return l / r;
}
return 0;
}
}