栈
栈(stack)是限定仅在表尾进行插入和删除操作的线性表
栈的基础操作
push( item ) 插入元素item为新的栈顶元素
pop( ) 返还栈顶元素值,并删除栈顶元素
peek() 查看栈顶元素
empty() 判断栈是否为空
栈的应用——四则运算求值
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String str = scanner.next();
char[] arr = str.toCharArray();
LinkedList<String> prefix = StrInList(str);
LinkedList<String> postfix = prepost(prefix);
System.out.println(arithmetic(postfix));
}
/**
* 利用栈取出运算
*
* @param postfix
* @return
*/
private static int arithmetic(LinkedList<String> postfix) {
Stack<String> tempStack = new Stack<>();
String priority = "+-*/()";
int result = 0;
for (String temp : postfix) {
if (priority.indexOf(temp) > -1) {//判断的字符是否为运算符
int T = Integer.parseInt(tempStack.pop());
result = Integer.parseInt(tempStack.pop());//取出上一步的运算结果
switch (temp) {
case "+":
result += T;
break;
case "-":
result -= T;
break;
case "*":
result *= T;
break;
case "/":
result /= T;
break;
}
tempStack.push(result + "");
} else {
tempStack.push(temp);
}
}
return result;
}
/**
* 利用栈结构 将中缀表达式改为后缀表达式
*
* @param prefix
* @return
*/
private static LinkedList<String> prepost(LinkedList<String> prefix) {
LinkedList<String> postfix = new LinkedList<>();
Stack<String> tempStack = new Stack<>();
HashMap<String, Integer> priority = new HashMap<>();
priority.put("+", 1);
priority.put("-", 1);
priority.put("*", 2);
priority.put("/", 2);
priority.put("(", 3);
priority.put(")", 3);
int sum = 0;//判断运算符是否连续出现
for (String temp : prefix) {
if (priority.get(temp) != null) {//判断temp是是不是运算符
int index = priority.get(temp);
sum++;
//tempstack是否为空 或 运算符连续出现 注意:不能让 ")"直接进入
if (tempStack.empty() || sum > 1 && temp.equals(')')) {
tempStack.push(temp);
sum = 0;
} else if (index <= priority.get(tempStack.peek())) {//当前运算符和栈顶运算符比较优先级
//将优先级高于或等于当前的运算符的运算符出栈 遇到 "(" 或 栈为空 时停止
while (index <= priority.get(tempStack.peek()) && !tempStack.peek().equals("(")) {
postfix.add(tempStack.pop());
if (tempStack.empty()) {
break;
}
}
//先让优先级高的出栈再进栈
tempStack.push(temp);
} else {
if (temp.equals(")")) {
//"("前面的运算符全部出栈
while (!tempStack.peek().equals("(")) {
postfix.add(tempStack.pop());
}
//"("出栈
tempStack.pop();
} else {
tempStack.push(temp);
}
}
} else {
postfix.add(temp);
}
}
while (!tempStack.empty()) {
postfix.add(tempStack.pop());
}
return postfix;
}
/**
* 将字符串转为Linkedlist数组 Linklist为链式结构
*
* @param str
* @return
*/
private static LinkedList<String> StrInList(String str) {
LinkedList<String> prefix = new LinkedList<>();
String priority = "+-*/()";
char[] arr = str.toCharArray();
StringBuilder tempstr = new StringBuilder();//判断数字
for (char temp : arr) {
if (priority.indexOf(temp) > -1) {//判断的字符是否为运算符
if (tempstr.length() > 0) {
prefix.add(tempstr.toString());
tempstr.setLength(0);
}
prefix.add(temp + "");
} else {
tempstr.append(temp);
}
}
if (tempstr.length() > 0) {
prefix.add(tempstr.toString());
}
return prefix;
}
}