简易计算器
中缀变后缀
遍历字符串数组:
-
操作数直接输出。
-
“*” “/” “(” -> 入栈。
-
“)” -> 栈元素弹出直到遇到左括号。(左括号只弹出并不输出)
-
“+” “-” -> 栈顶为操作数 则入栈;为运算符则 将其出栈。(可能多次出栈)
-
读完输入后,则将栈中剩余元素依次弹出。
peek() 前一定要 stack.isEmpty() == fasle !!!
// 返回类型根据需求更改
public static String[] mlConvert(String str) {
Stack<String> op = new Stack<>();
ArrayList<String> out = new ArrayList<>(); // 存后缀表达式
String[] s = str.split("");
StringBuilder result = new StringBuilder();
for (String c : s) {
switch (c) {
case "*":
case "/":
case "(":
op.push(c); // 压制“弱小”
break;
case "+":
case "-":
while (!op.isEmpty()) {
if(op.peek().equals("+") || op.peek().equals("-") || op.peek().equals("*") || op.peek().equals("/"))
out.add(op.pop()); // 移出优先级高(等)的运算符
else break;
}
op.push(c); // 压入自己
break;
case ")":
while (!op.isEmpty()) { // 匹配右括号
if(!op.peek().equals("("))
out.add(op.pop());
else break;
}
op.pop(); // "("
break;
default: // 数字
out.add(c);
break;
}
}
while (!op.isEmpty()){ // 剩余处理
out.add(op.pop());
}
String[] o = new String[out.size()];
for (int i = 0; i < out.size(); i++) {
o[i] = out.get(i);
}
return o;
}
逆波兰运算
public static int evalRPN(String[] tokens){ // 计算后缀表达式
int returnValue = 0;
String operators = "+-*/";
Stack<String> stack = new Stack<>();
for (String t : tokens) {
if(!operators.contains(t)){
stack.push(t); // 数字入栈
}else {
int a = Integer.parseInt(stack.pop());
int b = Integer.parseInt(stack.pop());
int index = operators.indexOf(t); // 觅符
switch (index) { // 计算并将结果入栈
case 0 -> stack.push(String.valueOf(a + b));
case 1 -> stack.push(String.valueOf(a - b));
case 2 -> stack.push(String.valueOf(a * b));
case 3 -> stack.push(String.valueOf(a / b));
}
}
}
returnValue = Integer.parseInt(stack.pop()); // 结果出栈
return returnValue;
}
Dijkstra(双栈)
参考算法(第四版)
-
操作数入操作数栈
-
运算符入运算符栈
-
忽略左括号
-
遇到右括号,弹出一个运算符及所需操作数,将计算结果压入操作数栈
public static void Dijkstra(String str){ //中缀表达式计算 Stack<String> ops = new Stack<>(); Stack<Double> vals = new Stack<>(); String[] s1 = str.split(""); for (String s : s1) { switch (s) { // case "(": break; case "+": case "-": case "*": case "/": case "sqrt": ops.push(s); break; case ")": { // String op = ops.pop(); double v = vals.pop(); switch (op) { case "+" -> v += vals.pop(); case "-" -> v -= vals.pop(); case "*" -> v *= vals.pop(); case "/" -> v /= vals.pop(); case "sqrt" -> v = Math.sqrt(v); } vals.push(v); break; } default: vals.push(Double.valueOf(s)); break; } } System.out.println(vals.pop()); }