这里仅讨论包含+ - * / ()的中缀表达式,并且没有对表达式合法性进行校验.
顺序遍历所给中缀表达式串的每个字符:
- 若是数字,直接输出
- 若是符号,分情况讨论.
通常是当前符号比栈顶符号优先级高时,当前符号才入栈.(优先级相同时仍是先出栈后压栈,因为同优先级计算方式是顺序的,从左到右)
+和-优先级最低,只有栈为空或者栈顶符号是左括号(时才入栈;
乘和除优先级高一些,栈为空或者栈顶不是* 和/号时入栈.
左括号(直接入栈.
若是右括号),则不断出栈直到遇上左括号(. 将左括号(也出栈,注意右括号不入栈
例 KS34
代码参考Java版
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
String s = scan.nextLine();
// 中缀表达式转后缀
List<String> res = ParseStr(s);
// 计算后缀表达式的值
int ans = getValue(res);
System.out.println(ans);
}
private static List<String>ParseStr(String s){
Stack<String>stack = new Stack<>();
List<String>list = new ArrayList<>();
for(int i=0;i<s.length();++i){
String tmp = String.valueOf(s.charAt(i));
switch(tmp){
case "+":
case "-":
// 加减号只有栈为空或者栈顶是'('才能入栈
while(!stack.empty()&& !stack.peek().equals("("))
list.add(stack.pop());
stack.push(tmp);
break;
case "*":
case "/":
// 乘除号在栈空或者栈顶不为乘除号时入栈
while(!stack.empty()&& (stack.peek().equals("*")||stack.peek().equals("/")))
list.add(stack.pop());
stack.push(tmp);
break;
case "(":
// 左括号直接入栈
stack.push(tmp);
break;
case ")":
// 若是右括号,不断出栈直到遇到左括号.将左括号也出栈, 注意这里右括号不入栈
while(!stack.empty()&& !stack.peek().equals("("))
list.add(stack.pop());
stack.pop();
break;
// 数字
default:
int sum = Integer.parseInt(tmp);
while(i+1<s.length()&&s.charAt(i+1)<='9'&&s.charAt(i+1)>='0')
{
sum = sum * 10 + (s.charAt(i+1)-'0');
++i;
}
list.add(String.valueOf(sum));
}
}
while(!stack.empty())
list.add(stack.pop());
return list;
}
// 后缀表达式计算:遇到操作符,从栈顶弹出两个操作数进行计算.注意操作数的先后顺序.将计算完的结果压栈.
// 反复进行,直到最后栈内剩下一个元素. 就是计算结果
private static int getValue(List<String>list){
Stack<Integer>stack = new Stack<>();
for(String s:list){
switch(s){
case "+":
stack.push(stack.pop()+stack.pop());
break;
case "-":
int b = stack.pop();
int a = stack.pop();
stack.push(a-b);
break;
case "*":
stack.push(stack.pop()*stack.pop());
break;
case "/":
int b1 = stack.pop();
int a1 = stack.pop();
stack.push(a1/b1);
break;
default:
stack.push(Integer.parseInt(s));
}
}
return stack.pop();
}
}
京公网安备 11010502036488号