手记

中缀表达式转为后缀表达式

问题:输入一个式子3*(4+15)-6=?,输出结果
这个问题主要用到了栈解决,首先这个式子是中缀表达式,然后得转换成后缀表达式,然后再进行求值。因为对计算机来说,计算前缀或后缀表达式的值非常简单。
不明白什么是中缀表达式后缀表达式的同学看这里:

举例:
(3 + 4) × 5 - 6 就是中缀表达式

  • × + 3 4 5 6 前缀表达式
    3 4 + 5 × 6 - 后缀表达式

前缀、中缀、后缀表达式详细介绍

bug给我在图书馆里讲了一下具体实现的过程,对,我一个大四的学姐求着大二的学弟教我数据结构TAT。简单的说,就是先将一个表达式拆分出来,运算符放在一个栈里,操作数放在一个栈里,然后通过运算符优先往栈里压数据或弹出计算。
我这样说比较难懂,如果能画图的话就比较直观了
还是祭出代码吧,写得比较差劲,大家将就着看

主函数

public static void main(String[] args) {
        // TODO Auto-generated method stub
        Stack tr=new Stack();//存放符号的栈 
        Stack nd=new Stack();//存放操作数的栈
        char[] op=new char[]{'*','+','-','/','(',')','#'};//操作符数组
        tr.push('#');//#为起始符号
        System.out.println("请输入表达式(以#结束):");
        Scanner so=new Scanner(System.in);
        String s=so.next();
        int len=s.length();
        int i=0;
        while(i<len){
        char c=s.charAt(i);//接收单个字符
        while(c!='#'(char)tr.peek()!='#'){//当栈顶不为空时或未结束时
            if(in(c,op)){
                nd.push(c); 
                c=s.charAt(++i);
            }
            else{
                switch(precede((char)tr.peek(),c)){
                    case'<':
                        tr.push(c);//如果tr栈顶符号优先权低于c符号,则c符号进栈
                        c=s.charAt(++i);
                        break;
                    case'='://脱括号并接收下一字符
                        tr.pop();
                        c=s.charAt(++i);
                        break;
                    case'>'://退栈并将运算结果入栈        
                        int b= Integer.parseInt(String.valueOf(nd.pop()));//强制转换为int型
                        int a=Integer.parseInt(String.valueOf(nd.pop()));
                        nd.push(operate(a,(char)tr.pop(),b));
                        break;
                }
            }
            }
        i++;
        }
        System.out.println("运算结果为:"+nd.peek());

    }

in方法,用于判断字符是不是操作符

public static boolean in(char c){
        char[] op=new char[]{'*','+','-','/','(',')','#'};//操作符数组
        for(int i=0;i<op.length;i++)
        {
            if(c==op[i])
                return false;
        }   
        return true;
    }

precede方法,用于判断运算符之间的优先级,返回优先关系

public static char precede(char a,char c){
        switch(a){
        case'+':
        case'-':
            switch(c){
            case'+':
            case'-':
            case')':
            case'#':
                return '>';
            case'*':
            case'/':
            case'(':
                return '<';
            }
        case'*':
        case'/':
            switch(c){
            case'+':
            case'-':
            case')':
            case'#':
            case'*':
            case'/':
                return '>'; 
            case'(':
                return '<';
            }

        case'(':
            switch(c){
            case'+':
            case'-':
            case'*':
            case'/':
            case'(':    
                return '<';
            case')':
                return '=';
            case'#':
                return '0';
            }
        case')':
            switch(c){
            case'+':
            case'-':
            case')':
            case'#':
            case'*':
            case'/':
                return '>';
            case'(':
                return '0';
            }
        case'#':
            switch(c){
            case'+':
            case'-':
            case'(':
            case'*':
            case'/':
                return '<';
            case'#':
                return '=';
            case')':
                return '0';
            }
        }
        return c;

    }

operate方法,用于进行二元计算,返回计算结果

    public static int operate(int a,char t,int b){
        switch(t){
        case'+':return (a+b);
        case'-':return (a-b);
        case'*':return (a*b);
        case'/':return (a/b);
        }
        return 0;
    } 
2人推荐
随时随地看视频
慕课网APP