将中缀表达式转为后缀表达式和前缀表达式

来源:互联网 发布:jquery 反序列化json 编辑:程序博客网 时间:2024/05/21 10:06

中缀表达式

中缀表达式是一种常用的算术或逻辑公式表示方法,操作符一中缀形式处于操作数中间。中缀表达式是人们常用的算术表示方法。
虽然人的电脑很容易理解与分析中缀表达式,但对于计算机来说中缀表达式却很复杂的,因此计算表达式的值,通常需要先将中缀表达式转换为前缀或后缀表达式。
例如:3+5+7-8

前缀表达式

运算符位于操作数之前
例如:-++3578

后缀表达式:

运算符位于操作符之后
例如:
35+7+8-

将中缀表达式转为前缀表达式

  • 初始化两个栈,一个运算符栈S1,一个存中间结果的栈S2
  • 从右到左开始遍历表达式
  • 遇到运算符,将其压入S1
    • 如果S1为空,或栈顶运算符为右括号“)”,则直接将此运算符入栈
    • 否则,若优先级比栈顶运算符较高或者相等, 也将运算符压入S1
    • 否则,将S1栈顶的元素压入到S2中,再次转到遇到运算符那一步
  • 遇到操作数,将其压入S2
  • 遇到括号的时候:
    • 如果是右括号“)”,则直接压入S1
    • 如果是左括号“(”,则一次弹出S1栈顶的运算符,并压入S2,直到遇到右括号“)”,此时,将这一对括号丢弃
  • 重复2到5的步骤,直到表达式的最左边
  • 将S1中剩余的运算符依次弹出并压入S2
  • 依次弹出S2中的运算符并输出,结果即为中缀表达式对应的前缀表达式

Java代码:

public static String zhongzhui(String biaodashi){        String result = " ";        int i;        Stack<Character> S1 = new Stack<>();        Stack<Character> S2 = new Stack<>();        int provity = 0;        for(i = biaodashi.length()-1;i>=0;i--){            char temp = biaodashi.charAt(i);            if((temp >=48 && temp <=57 )|| temp == ')'){                if(temp != ')'){                    S2.push(temp);                }else{                    S1.push(temp);                    provity = 0;                }            }else if(temp == '('){                char ch;                while((ch = S1.pop())!=')'){                    S2.push(ch);                    System.out.println(ch);                }                provity = getProvity(S1.peek());                System.out.println(provity);            }else if(S1.isEmpty() || S1.peek() == ')' || getProvity(S1.peek()) <= getProvity(temp)){                provity = getProvity(temp);                S1.push(temp);                System.out.println(temp);            }else{                while(provity> getProvity(temp)){                    S2.push(S1.pop());                    if(S1.isEmpty()){                        break;                    }                    provity = getProvity(S1.peek());                }                S1.push(temp);                provity = getProvity(S1.peek());            }        }        while(!S1.isEmpty()){            S2.push(S1.pop());        }        StringBuilder s = new StringBuilder();        while(!S2.isEmpty()){            s.append(S2.pop());        }        result = s.toString();        return result;    }    public static int getProvity(char ch){        switch(ch){        case '+':        case '-':            return 1;        case 'x':        case '/':            return 2;        }        return 0;    }

例如 输入的表达式:”1+((2+3)×4)-5”
结果:-+1×+2345
ps:这段代码只能计算一位数的加减乘除,而且除不准确,想要进行多位数的,请自己修改。

计算机如何计算前缀表达式:

从右到左遍历前缀表达式,遇到数字,入栈,遇到运算符,弹出栈顶的两个元素,用运算符进行计算,将结果入栈。重复上述结果到遍历完成,最后栈中的结果就是表达式的结果

public static char GetResult(String qianzhui){        char result = ' ';        Stack<Character> S1 = new Stack<>();        int i ;        for(i = qianzhui.length()-1;i>=0;i--){            char temp = qianzhui.charAt(i);            if(temp>=48&&temp <=57){                S1.push(temp);            }else{                char num2 = S1.pop();                char num1 = S1.pop();                char num3=' ';                int t;                switch(temp){                case '+':                      t= num2-48+num1-48;                    num3 = (char)(t +48);                    break;                case '-':                    t = num2-48-(num1-48);                    num3 = (char)(t +48);                    break;                case 'x':                    t = (num2-48)*(num1-48);                    num3 = (char)(t +48);                    break;                case '/':                    t = (num2-48)/(num1-48);                    num3 = (char)(t +48);                    break;                }                S1.push(num3);            }        }        result = S1.pop();        return result;    }

中缀表达式转成后缀表达式

  • 初始化两个栈:运算符栈S1,和操作数栈S2
  • 从左到右遍历表达式
  • 遇到操作数,压入S2
  • 遇到运算符,比较与S1栈顶运算符的优先级:
    • 如果S1为空,或者栈顶元素为左括号“(”,则直接压入S1
    • 否则,若优先级比栈顶运算符高,直接压入S1
    • 否则,将S1栈顶运算符弹出压入S2,再转到如果S1为空那一步
  • 遇到括号的时候:
    • 如果是左括号“(”,直接压入S1
    • 如果是右括号,则依次弹出S1栈顶的运算符,并压入S2,直到遇到左括号
  • 重复2-5步,直到遍历完成
  • 将S1中剩余的运算符压入S2
  • S2中元素的逆序就是后缀表达式
public static String getHouzhui(String biaodashi){        String result = "";        int i;        Stack<Character> S1 = new Stack<>();        Stack<Character> S2 = new Stack<>();        int provity = 0;        for(i = 0; i<biaodashi.length();i++){            char temp = biaodashi.charAt(i);            System.out.println(temp+"yyyyy");            if((temp >=48 && temp <=57)|| temp == '('){                if(temp !='('){                    S2.push(temp);                }else{                    S1.push(temp);                    provity = 0;                }            }else if(temp == ')'){                char ch;                while((ch = S1.pop())!='('){                    S2.push(ch);                    System.out.println(ch+"ddddd");                }                provity = getProvity(S1.peek());                System.out.println(provity+"ddddd");            }else if(S1.isEmpty() || S1.peek() == '(' || getProvity(temp) > getProvity(S1.peek())){                if(S1.isEmpty()) System.out.println("empty");                S1.push(temp);                provity = getProvity(temp);                System.out.println(temp);            }else{                while(getProvity(temp)<= getProvity(S1.peek())){                    S2.push(S1.pop());                    if(S1.isEmpty()){                        break;                    }                    provity = getProvity(S1.peek());                }                S1.push(temp);                System.out.println(temp+"ssss");                provity = getProvity(S1.peek());            }        }        while(!S1.isEmpty()){            S2.push(S1.pop());        }        String rs=" ";        while(!S2.isEmpty()){            rs+=S2.pop();        }        return rs;    }    public static int getProvity(char ch){        switch(ch){        case '+':        case '-':            return 1;        case 'x':        case '/':            return 2;        }        return 0;    }

计算机计算后缀表达式

从左至右扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(次顶元素 op 栈顶元素),并将结果入栈;重复上述过程直到表达式最右端,最后运算得出的值即为表达式的结果。

    public static char getResult(String houzhui){        char result = ' ';        Stack<Character> S1 = new Stack<>();        int i ;        for(i = 0;i<houzhui.length();i++){            char temp = houzhui.charAt(i);            if(temp>=48&&temp <=57){                S1.push(temp);                System.out.println(temp+"aaaaaaaa");            }else{                char num2 = S1.pop();                char num1 = S1.pop();                char num3=' ';                int t;                switch(temp){                case '+':                      t= num1-48+num2-48;                    num3 = (char)(t +48);                    break;                case '-':                    t = num1-48-(num2-48);                    num3 = (char)(t +48);                    break;                case 'x':                    t = (num1-48)*(num2-48);                    num3 = (char)(t +48);                    break;                case '/':                    t = (num1-48)/(num2-48);                    num3 = (char)(t +48);                    break;                }                S1.push(num3);                System.out.println(num3-48);            }        }        result = S1.pop();        return result;    }

本篇参考于
http://blog.csdn.net/antineutrino/article/details/6763722/