[算法提升]后缀表达式真题

260 阅读1分钟

中缀表达式转后缀表达式

中缀便于人类阅读,后缀便于计算机计算
中缀:1+((2+3)*4)-5
后缀:123+4*+5-

  • 当前元素为操作数,直接加入StringBuilder builder
  • 操作符栈opStack为空或遇到(,或当前直接符号优先级高于栈顶,符号直接入栈
  • 符号优先级小于等于栈顶,栈顶出栈,加入builder,比较该符号与新的栈顶符号,最后入栈
  • 遇到),当栈顶元素不是(,就弹出操作符,加入builder。直到遇到(,弹出(,()都丢弃
  • 最后将栈内剩余的符号弹出,加入builder

bilibili java工程师真题

Q: 题目描述 给定一个合法的表达式字符串,其中只包含非负整数、加法、减法以及乘法符号(不会有括号),例如7+345+2+4-3-1,请写程序计算该表达式的结果并输出;

输入描述: 输入有多行,每行是一个表达式,输入以END作为结束

A:

import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner in =new Scanner(System.in);
        while(in.hasNext()){
            String express=in.nextLine();
            if(express.contains("END")){
                break;
            }else{
                Main main=new Main();
                String sufix=main.infix2Sufix(express);
                int result=main.calsufix(sufix);
                System.out.println(result);
            }
        }
    }
     
    //calculate sufix
    public int calsufix(String express){
        //num push, operator pop two nums calculate and push
        Stack<Integer> numStack=new Stack<>();
        String[] expressArr=express.split(" ");
        for(int i=0;i<expressArr.length;i++){
            if(isNumber(expressArr[i])){
                numStack.push(Integer.valueOf(expressArr[i]));
            }else{
                int num1=numStack.pop();
                int num2=numStack.pop();
                int result=cal(num2,num1,expressArr[i]);//num2 num1 
                numStack.push(result);
            }
        }
        return numStack.pop();
    }
     
    public String infix2Sufix(String s){
        StringBuilder builder=new StringBuilder();
        Stack<Character> opStack=new Stack<>();//opstack
        char[] sarr=s.trim().toCharArray();
        for(int i=0;i<sarr.length;){
            char cur=sarr[i];
            if(cur>='0' && cur<='9'){
                while(i<sarr.length && sarr[i]>='0' && sarr[i]<='9'){
                    builder.append(sarr[i]);//sarr[i]
                    i++;//merge 23 in infix
                }
                builder.append(" ");
            }else{
                if(cur==')'){
                    while(!opStack.isEmpty() && opStack.peek()!='('){
                        builder.append(opStack.peek());
                        builder.append(" ");
                        opStack.pop();
                    }
                    while(!opStack.isEmpty() && opStack.peek()=='('){
                        opStack.pop();
                    }
                }else if(getPriority(cur)==1 || getPriority(cur)==0){//exist priority comparison
                    while(!opStack.isEmpty() && hasLowerOrEqualPriority(cur,opStack.peek())){
                        builder.append(opStack.peek());
                        builder.append(" ");
                        opStack.pop();
                    }
                    //finally push
                    opStack.push(cur);
                }else{
                    opStack.push(cur);
                }
                i++;
            }
        }
        //pop all remaining operators
        while(!opStack.isEmpty()){
            builder.append(opStack.pop());
            builder.append(" ");
        }
        return builder.toString();
    }
     
    private boolean hasLowerOrEqualPriority(char s1,char s2){
        if(getPriority(s1)<=getPriority(s2)){
            return true;
        }else{
            return false;
        }
    }
     
    private int getPriority(char s1){
        if(s1=='*'||s1=='/'){
            return 1;
        }else if(s1=='+'||s1=='-'){
            return 0;
        }else{
            return Integer.MIN_VALUE;
        }
    }
     
    private boolean isNumber(String s){
        try{
            Integer.valueOf(s);
            return true;
        }catch(Exception e){
            return false;
        }
    }
     
    private int cal(int num1, int num2, String op){
        switch(op){
            case "+":
                return num1+num2;
            case "-":
                return num1-num2;
            case "*":
                return num1*num2;
            case "/":
                return num1/num2;
            default:
                return 0;
        }
    }
}

牛客实战