Java-Stack实现中序表达式求值

来源:互联网 发布:淘宝助理官方下载 免费 编辑:程序博客网 时间:2024/05/29 18:00

中序表达式:对人而言是很直观的(我们平时计算时接触最多的表达式),但计算机处理起来比较麻烦(括号、优先级之类的),前序和后序表达式中没有括号,而且在计算中只需单向扫描,不需要考虑运算符的优先级。如2+3*4+5。

前序表达式:又称为前缀表达式,不含括号的算术表达式,而且它是将运算符写在前面,操作数写在后面的表达式,例如:"+ 2 + * 3 4  5",也称为“波兰式”。它运算时需要注意是从右往左结合,也就是运算符的右侧的两个数字进行运算, 因为'+' 比'*'优先级低, 此时先计算3*4,表达式变为"+ 2 + 12  5", 再将  12 + 5, 表达式变为"+ 2 17",最终得结果19。

后序表达式:与前序表达式扫描方式正好相反,例如:"2 3 4 * 5 + + ",它计算时是按从左往右结合,运算符左侧的两个数字进行计算,遇到第一个’*',计算 3*4,表达式变为"2 12 + 5 +", 在计算2 + 12,表达式变为"14 5 +",最终得到结果19。

 

本篇主要讲中序表达式,下面看用栈实现中序表达式的具体过程:

1.先将表达式转换为字符,判断字符是数字还是运算符,数字push到运算数栈, 运算符和括号push到运算符栈。

2.需要考虑运算符的优先级,'*', '/' 的优先级大于 '+', '-'先对优先级高的运算符进行出栈计算。

3.当左括号'('入栈时,继续第2步操作,直到匹配到右括号')'。

4.运算符栈为空,运算结束,返回运算数栈结果。







说了这么多,上代码:

public class InfixExpr {    public static float evaluate(String expression) {char[] tokens = expression.toCharArray();Stack<Float> stackOfNum = new Stack<Float>();Stack<Character> stackOfOps = new Stack<Character>();for (int i = 0; i < tokens.length; i++) {    if (tokens[i] == ' ')continue;    if (tokens[i] >= '0' && tokens[i] <= '9') {StringBuffer sbuf = new StringBuffer();while (i < tokens.length && tokens[i] >= '0' && tokens[i] <= '9') {    sbuf.append(tokens[i++]);}i--; // 回退一位stackOfNum.push(Float.parseFloat(sbuf.toString()));    }    else if (tokens[i] == '(')stackOfOps.push(tokens[i]);    else if (tokens[i] == ')') {while (stackOfOps.peek() != '(')    stackOfNum.push(caculate(stackOfOps.pop(), stackOfNum.pop(), stackOfNum.pop()));stackOfOps.pop();    }    else if (tokens[i] == '+' || tokens[i] == '-' || tokens[i] == '*' || tokens[i] == '/') {while (!stackOfOps.empty() && hasPrecedence(tokens[i], stackOfOps.peek()))    stackOfNum.push(caculate(stackOfOps.pop(), stackOfNum.pop(), stackOfNum.pop()));stackOfOps.push(tokens[i]);    }}while (!stackOfOps.empty())    stackOfNum.push(caculate(stackOfOps.pop(), stackOfNum.pop(), stackOfNum.pop()));return stackOfNum.pop();    }    public static boolean hasPrecedence(char op1, char op2) {if (op2 == '(' || op2 == ')')    return false;if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-'))    return false;else    return true;    }    public static float caculate(char op, float b, float a) {switch (op) {case '+':    return a + b;case '-':    return a - b;case '*':    return a * b;case '/':    if (b == 0) {throw new UnsupportedOperationException("Cannot divide by zero");    }    return a / b;}return 0;    }    public static void main(String[] args) {System.out.println(InfixExpr.evaluate("2 + 3 * 4 + 5"));System.out.println(InfixExpr.evaluate("100 * 2 + 12"));System.out.println(InfixExpr.evaluate("100 * ( 2 + 12 )"));System.out.println(InfixExpr.evaluate("100 * ( 2 + 12 ) / 14"));    }}


最后附上刘欣老师的代码: 参考代码

                                             
0 0
原创粉丝点击