关于中缀表达式求值 (四则运算和括号,支持多位数)

时间:2020-12-30 19:30:10

1.中缀转后缀和计算后缀表达式

  1.1 中转后

  1. 数字则输出
  2. 如果是 "(" ,直接入栈
  3. 如果是 ")", 栈顶元素出栈并输出,直到遇到" (",只弹出。
  4. 如果栈空,直接入栈,否则和栈顶比较优先级,当大于栈顶时,入栈,否则,栈顶元素退栈,直到大于栈顶或栈空
  5. 中缀表达式扫描完毕,若栈不空,将其内所有元素弹出。

  1.2 计算后缀

  1. 数字则入栈
  2. 运算符,出栈b,再出栈a 计算c=a operate b,将c入栈
  3. 中缀表达式扫描完毕,将栈内唯一的元素(也就是求的值)弹出并返回。

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();
    }

}