package org.example.test;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Stack;
public class SolveTest {
public static void main(String[] args) {
String s = "a/b+(c*d-e*f)/g";
// System.out.println(getSuffix(s));
String s1 = "3+2*3*4-1";
System.out.println(solve(s1));
}
/**
* 顺序扫描表达式的每一项,然后根据他的类型做如下相应操作:
* 若该项是操作数,则将其压入栈中,
* 若该项是操作符<op>,则连续从栈中退出两个操作数Y和X, 形成运算指令 X<op>Y,并将计算结果压入栈中。
* 当表达式的所有项都扫描并处理万后,栈顶存放的就是最后计算的结果。
*
* @param s
* @return
*/
public static int solve(String s) {
// write code here
Set<String> ops = new HashSet<>();
ops.add("+");
ops.add("-");
ops.add("*");
ops.add("/");
String suffix = getSuffix(s);
System.out.println(suffix);
Stack<Integer> stack = new Stack<>();
String[] list = suffix.split(",");
for (String c : list) {
if (ops.contains(c)) {
int a = stack.pop();
int b = stack.pop();
int sum = 0;
if (c.equals("+")) {
sum = a + b;
} else if (c.equals("-")) {
sum = b - a;
} else if (c.equals("*")) {
sum = a * b;
}
stack.push(sum);
} else {
stack.push(Integer.valueOf(c));
}
}
return stack.pop();
}
/**
* 转换为后缀表达式,使用逗号把每个部分隔离,保证100等超过2位数的数字出现问题。
* 将中缀表达式转换为后缀表达式的算法思想如下:
* 从左向右开始扫描中缀表达式,
* 遇到数字时,加入后缀表达式,
* 遇到运算符时:
* a. 若为'(', 入栈。
* b. 若为')',则以次把栈中的运算符加入后缀表达式,直到出现'(', 从占中删除'('。
* c. 若为除括号以外的其他运算符,当其优先级高于除'('外的栈顶运算符时,直接入栈,否则从栈顶开始,以次弹出比当前处理的运算符
* 优先级高或者相等的运算符,直到一个比它优先级低的或者遇到'('为止。
*
* @param s
* @return
*/
private static String getSuffix(String s) {
Stack<Character> stack = new Stack<>();
StringBuilder buffer = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '+' || c == '-') {
buffer.append(",");
if (!stack.isEmpty() && (stack.peek() == '-' || stack.peek() == '*' || stack.peek() == '+' || stack.peek() == '/')) {
buffer.append(stack.pop());
buffer.append(",");
}
stack.push(c);
} else if (c == '*' || c == '/') {
buffer.append(",");
if (!stack.isEmpty() && (stack.peek() == '*' || stack.peek() == '/')) {
buffer.append(stack.pop());
buffer.append(",");
}
stack.push(c);
} else if (c == '(') {
stack.push(c);
} else if (c == ')') {
while (stack.peek() != '(') {
buffer.append(",");
buffer.append(stack.pop());
}
stack.pop();
} else {
buffer.append(c);
}
}
while (!stack.isEmpty()) {
buffer.append(",");
buffer.append(stack.pop());
}
return buffer.toString();
}
}