中缀表达式转后缀表达式详解(Java描述)

先扯个蛋@.@

后缀表达式,做用在于方便计算机来计算表达式的一种表达式。=。=好啰嗦。
直接举一个例子吧:
好比ab*cd+/:
从左到右扫描,扫描到一个运算符,就将前面两个数字来作运算
ab*—->变成a*b,做为一个总体的值。而后继续扫描到+号,就把cd加起来成为一个总体的值c+d,而后继续扫描到/号,就把前面计算的两个值相除,即(a*b)/(c+d)。这个表达式是咱们容易读的,叫作中缀表达式。为了可以让计算机能很好的计算,咱们要把它变成后缀表达式。java


而后不罗嗦,直接上代码

public class nifix2postfix {
    public static Map<Character, Integer> privMap;
    public static StringBuffer postFixBuffer = new StringBuffer();
    public static void findPostFix(String nifix){
        //初始化运算符的优先级
        privMap = new HashMap<Character, Integer>();
        privMap.put('*', 2);
        privMap.put('/', 2);
        privMap.put('+', 1);
        privMap.put('-', 1);
        //后缀表达式结果

        //操做符栈
        Stack<Character> operatorsStack = new Stack<Character>();
        //从第一位读取
        for(int i=0;i<nifix.length();++i){
            char read = nifix.charAt(i);
            System.out.println("读取的字符是:"+read);
            //若是是数字,就直接放入postFixBuffer中(这里的数字用小写字母来表示)
            if(read>='a'&&read<='z'){
                postFixBuffer.append(read);
                continue;
            }
            //若是是操做符
            else if(privMap.containsKey(read)){

                if(operatorsStack.size()!=0){

                    int stackSize = operatorsStack.size();
                    for(int m = 0;m<stackSize;++m){
                        char c = operatorsStack.peek();
                        //1.若是比栈顶的优先级要高,就直接放到栈中,或者弹没了
                        if(privMap.get(c)<=privMap.get(read)||operatorsStack.size()==0)
                        {
                            System.out.println(read+" 优先级比栈顶的"+c+"优先级高,因此放入栈中");
                            operatorsStack.push(read);
                            break;
                        }
                        //2.若是比栈顶的要低,就把在栈中比它优先级高的都放到结果中后,再压入栈中
                        else{
                            System.out.println("将优先级大的:"+c+" 弹出");
                            postFixBuffer.append(operatorsStack.pop());
                            if(operatorsStack.size()==0)
                                operatorsStack.push(read);
                        }
                    }

                }
                else{
                    System.out.println("因为栈内没有元素,因此直接压入:"+read);
                    operatorsStack.push(read);
                }

            }
            else if(read=='('){
                int range = i;

                Stack<Character> match = new Stack<Character>();
                match.push(nifix.charAt(i));
                for(int temp=i+1;temp<=nifix.length();++temp){
                    if(match.isEmpty()){
                        range = temp;
                        break;
                    }
                    if(nifix.charAt(temp)==')'){

                        match.pop();
                    }
                    else if(nifix.charAt(temp)=='(')
                        match.push('(');
                }
                //递归找到括号内的后缀表达式
                System.out.println("递归作:"+nifix.substring(i+1, range-1));
                findPostFix(nifix.substring(i+1, range-1));
                i = range+1;
            }

        }
        while(operatorsStack.size()!=0){
            postFixBuffer.append(operatorsStack.pop());
        }

        System.out.println(postFixBuffer);
// return postFixBuffer.toString();

    };
}

算法解释

首先要定义一个privMap,一个HashMap,用于储存某个运算符的优先级的。接下来,扫描的过程是:
1.从左到右扫描表达式
2.若是遇到数字,直接加入后缀表达式
3.若是遇到操做符,若是其优先级比栈内元素都高,就放入栈中。相反,把栈内优先级比该操做符高的都pop到后缀表达式中
4.遇到括号的话经常使用递归,找到括号内的表达式,而后传给同一个函数处理web