1.中缀转后缀和计算后缀表达式
1.1 中转后
- 数字则输出
- 如果是 "(" ,直接入栈
- 如果是 ")", 栈顶元素出栈并输出,直到遇到" (",只弹出。
- 如果栈空,直接入栈,否则和栈顶比较优先级,当大于栈顶时,入栈,否则,栈顶元素退栈,直到大于栈顶或栈空
- 中缀表达式扫描完毕,若栈不空,将其内所有元素弹出。
1.2 计算后缀
- 数字则入栈
- 运算符,出栈b,再出栈a 计算c=a operate b,将c入栈
- 中缀表达式扫描完毕,将栈内唯一的元素(也就是求的值)弹出并返回。
2.代码如下
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;;
public class Test4 {
private static Map<Character,Integer> map=new HashMap<>();
static {
map.put('+', 0);
map.put('-', 0);
map.put('*', 1);
map.put('/', 1);
}
private static List<String> toPost(String target){
List<String> post=new ArrayList<>();
Stack<Character> stk=new Stack<>();
Pattern p=Pattern.compile("\d+|\D");
Matcher m=p.matcher(target);
while(m.find()) {
String e=m.group();
if(e.matches("\d+"))
post.add(e);
else if(e.equals("("))
stk.push('(');
else if(e.equals(")")){
while(stk.peek()!='(')
post.add(stk.pop()+"");
stk.pop();
}else {
char op=e.charAt(0);
while(!stk.isEmpty()&&stk.peek()!='('
&&map.get(op)<=map.get(stk.peek()))
post.add(stk.pop()+"");
stk.push(op);
}
}
while(!stk.isEmpty()) post.add(stk.pop()+"");
return post;
}
private static int calcuPost(List<String> post) {
Stack<Integer> stk=new Stack<>();
for(String s:post) {
if(s.matches("\d+")) stk.push(Integer.parseInt(s));
else {
char c=s.charAt(0);
int b=stk.pop();
int a=stk.pop();
int t=0;
if(c=='+')
t=a+b;
else if(c=='-')
t=a-b;
else if(c=='*')
t=a*b;
else
t=a/b;
stk.push(t);
}
}
return stk.pop();
}
public static void main(String[] args) {
Scanner is=new Scanner(System.in);
while(is.hasNext()) {
String exp=is.next();
System.out.println(calcuPost(toPost(exp)));
}
is.close();
}
}