import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
public class StackDemo {
public static void main(String[] args) {
List<String> list = getList("15+(1*(6/2))*20");
System.out.println(list);
List<String> postfixExpression = getPostfixExpression(list);
System.out.println(postfixExpression);
System.out.println(getResult(postfixExpression));
}
//将算式保存到拆分到list中
public static List<String> getList(String str) {
ArrayList<String> list = new ArrayList();
String temp = ""; //用来保存连续的数字
for (int i = 0; i < str.length(); i++) {
if (48 <= str.charAt(i) && str.charAt(i) <= 58) { //根据字符的ASCII码来判断是不是数字
temp += str.charAt(i) + "";
} else { //不是数字,就是符号
if (temp != "") {
list.add(temp); //遍历到符号了,说明连续数字已结束,将数字保存到list中
temp = ""; //保存完需要清空
}
list.add(str.charAt(i) + ""); //将符号保存到list中
}
}
list.add(temp); //最后一个数字保存到list中
return list;
}
//得到后缀表达式
public static List<String> getPostfixExpression(List<String> list) {
ArrayList<String> newList = new ArrayList(); //用来保存后缀表达式的
Stack<String> strings = new Stack<>(); //使用栈暂存符号
for (int i = 0; i < list.size(); i++) {
if (list.get(i).matches("^-?[0-9]+$")) { //如果是数字直接放入list
newList.add(list.get(i));
} else { //不是数字就是符号
if (strings.empty()) { //如果栈是空的直接放入
strings.push(list.get(i));
} else if (list.get(i).equals("(")) { //如果是“(”也直接放入
strings.push(list.get(i));
} else if (list.get(i).equals(")")) { //如果是“)”需要将两个括号间的符号取出
while (!strings.peek().equals("(")) {
newList.add(strings.pop()); //取出两个括号间的符号
}
strings.pop();// 取完之后将“(”取出
} else {
if (priority(list.get(i)) > priority(strings.peek())) { //放入符号大于栈顶部符号的优先级,直接放入栈
strings.push(list.get(i));
} else { //放入符号小于等于栈顶部符号的优先级,将栈顶部的符号取出放入list,再将符号放入栈
newList.add(strings.pop());
strings.push(list.get(i));
}
}
}
}
while (!strings.empty()) { //最后将栈内的符号取出,放入list
newList.add(strings.pop());
}
return newList;
}
//给定符号优先级,值越大的优先级越高
public static int priority(String str) {
if (str.equals("+")) {
return 1;
}
if (str.equals("-")) {
return 1;
}
if (str.equals("*")) {
return 2;
}
if (str.equals("/")) {
return 2;
}
return -1;
}
//计算后缀表达式
private static int getResult(List<String> list) {
Stack<Integer> integers = new Stack<>();
int result = 0; //用来保存临时的计算结果
for (String str : list) {
if (str.matches("^-?[0-9]+$")) { //如果是数字直接入栈
integers.push(Integer.parseInt(str));
} else {
if (str.equals("+")) { //如果是加号,取出栈内两个元素,进行加法运算,将结果入栈
result = integers.pop() + integers.pop();
integers.push(result); //将结果入栈
result = 0; //结果需要清零
}
if (str.equals("-")) { //如果是减号,取出栈内两个元素,进行减法运算,将结果入栈
int num1 = integers.pop();
int num2 = integers.pop();
result = num2 - num1; //需要将后出栈的减先出栈的
integers.push(result);
result = 0;
}
if (str.equals("*")) { //如果是乘号,取出栈内两个元素,进行乘法运算,将结果入栈
result = integers.pop() * integers.pop();
integers.push(result);
result = 0;
}
if (str.equals("/")) { //如果是除号,取出栈内两个元素,进行除法运算,将结果入栈
int num1 = integers.pop();
int num2 = integers.pop();
result = num2 / num1; //需要将后出栈的除先出栈的
integers.push(result);
result = 0;
}
}
}
return integers.pop(); //最后存在栈内的数据就是结果
}
}