数据结构栈Stack之中缀表达式转后缀表达式运算应用

来源:互联网 发布:olga软件 编辑:程序博客网 时间:2024/05/16 02:37

通过学习java中的Stack栈,写一个一个简单的中缀表达式转换为后缀表达式并计算的应用

由于时间问题,没有写字符分割函数。暂时用空格进行分割

import java.util.Iterator;import java.util.Stack;public class Suffix2Infix {public static void main(String[] args) {// 创建对象OperaExpression oe = new OperaExpression();// 要计算得公式// 没有去写辨别多位数的字符串方法,于是目前使用空格进行区分符号与数字String ex = "9 + ( 3 - 1 * 3 ) * 3 + 10 / 2";// 输出结果System.out.println("结果:" + oe.getResult(ex));}}class OperaExpression {// 后缀表达式栈public Stack<String> exp = new Stack<String>();// 符号栈public Stack<String> sym = new Stack<String>();/** * 返回结果方法 * @param ex 中缀表达式 * @return 结果 */public double getResult(String ex) {// 中缀表达式转换为后缀表达式System.out.println("中缀表达式:" + ex.replaceAll(" ", ""));String ae = getAfterExpress(ex);System.out.println("后缀表达式:" + ae);// 计算结果double result = operaBackExpress();return result;}/** * 计算后缀表达式方法 * @return 表达式运算结果 */private double operaBackExpress() {// 创建结果栈Stack<Double> result = new Stack<Double>();// 遍历后缀表达式栈for (Iterator iterator = exp.iterator(); iterator.hasNext();) {// 得到栈内元素String string = (String) iterator.next();// 数字则存入结果栈if (getType(string) == 1) {result.push(Double.parseDouble(string));}// 如果非数字则进行计算else {// 取出结果栈内要计算的值double a2 = result.pop();double a1 = result.pop();// 对值进行计算double res = opera(a1, a2, string);// 讲结果存入结果栈result.push(res);}}// 取出结果栈内最终得结果return result.pop();}/** * 运算方法 * @param a1 第一个值 * @param a2 第二个值 * @param string 符号 * @return 计算结果 */private double opera(double a1, double a2, String string) {switch (string) {case "+":return a1 + a2;case "-":return a1 - a2;case "*":return a1 * a2;case "/":return a1 / a2;default:throw new RuntimeException(string + "运算错误");}}/** * 中缀表达式转后缀表达式方法 * @param ex 中缀表达式 * @return 后缀表达式栈 */private String getAfterExpress(String ex) {// 得到元素数组String[] spilt = getArray(ex);// 遍历数组for (String c : spilt) {// 得到元素类型int numOrsym = getType(c);switch (numOrsym) {// 1为数字,存入表达式栈case 1:exp.push(c + "");break;// 其他则进行符号判定,之后存入表达式栈default:// 进行符号判定checkSym();// 存入表达式栈sym.add(c);break;}}// 符号优先级插入运算,用于将剩余符号进行运算插入后最表达式栈highLevel(sym);// 讲后缀表达式栈转换为字符串String ae = "";for (Iterator iterator = exp.iterator(); iterator.hasNext();) {ae = ae + iterator.next();}// 返回字符串return ae;}/** * 表达式分解数组方法 * @param ex 中缀表达式 * @return 元素数组 */private String[] getArray(String ex) {String[] split = ex.split(" ");return split;}/** * 符号判定 */private void checkSym() {// 符号栈内元素超过一个时进入if (sym.size() > 1) {// 符号栈内包含左括号时进入if (sym.contains("(")) {// 如果符号栈内包含右括号,并且右括号为栈顶元素时进入if (sym.contains(")") && sym.indexOf(")") + 1 == sym.size()) {// 缓冲变量String i;// 创建括号内符号缓冲栈Stack<String> buffer = new Stack<String>();// 取出元素不等于左括号时运行while (!(i = sym.pop()).equals("(")) {// 取出元素如果为右括号,结束本次循环,进入下次循环if (i.equals(")"))continue;// 将符号存入符号缓存栈buffer.push(i);}// 将符号缓存栈进行优先级运算,并存入后缀表达式栈highLevel(buffer);}// 符号栈内不包含括号,并且符号元素为两个时进行运算} else if (sym.size() == 2) {// 将符号栈元素运算至后缀表达式栈popSym();}}}/** * 符号栈内多符号元素的优先级运算方法 * 运算后存入后缀表达式栈 * @param buffer 符号栈 */private void highLevel(Stack<String> buffer) {// 包含乘除法时while (buffer.contains("*") | buffer.contains("/")) {// 如果包含乘法if (buffer.contains("*")) {// 符号栈移除乘号buffer.removeElement("*");// 后缀表达式栈存入乘号exp.push("*" + "");}// 如果包含除法if (buffer.contains("/")) {// 符号栈溢出除号buffer.removeElement("/");// 后缀表达式栈存入除号exp.push("/" + "");}}// 剩余符号,无序存入后缀表达式栈while (buffer.size() != 0) {exp.push(buffer.pop() + "");}}/** * 符号栈内两元素优先级运算方法 * 运算后存入后缀表达式 */private void popSym() {// 取出第一个符号String a1 = sym.pop();// 取出第二个符号String a2 = sym.pop();// 通过符号类型运行优先级if (getType(a1) > getType(a2)) {exp.push(a1 + "");exp.push(a2 + "");} else {exp.push(a2 + "");exp.push(a1 + "");}}/** * 元素类型及符号优先级运算 * @param word 元素 * @return */private int getType(String word) {// 取出首位符号(主要用于辨别数字与符号)char[] cs = word.substring(0, 1).toCharArray();// 默认辨识符char one = '`';if (cs.length == 1) {// 首位符号作为辨识符one = cs[0];}// 如果首位元素的ascii码在0-9之间则为数字if (one >= '0' && one <= '9') {return 1;}// 否则则为符号else {switch (word) {case "(":return 41;case ")":return 42;case "*":return 31;case "/":return 32;case "+":return 21;case "-":return 22;default:throw new RuntimeException(word + "字段错误");}}}}
阅读全文
0 0
原创粉丝点击