java 逆波兰表达式 (后缀表达式) 计算器
2012-04-06 16:31
411 查看
在写计算器应用程序时,我们需要通过四则运算表达式构造逆波兰表达式,通过逆波兰表达式进行求值。
<注:逆波兰表达式,也称后缀表达式>
算法:需要构造运算符栈,通过进栈、出栈将愿表达式转换成为所需的逆波兰表达式。
转换过程:
(1)从左到右,依次读入,若读入字符是数字,则将其输出到逆波兰表达式列表。
(2)若读入字符是 '(' , 直接入栈;
若是 ‘)’,则采取出栈操作并顺序输出,直到 遇到第一个‘(‘ , ’(‘出栈不输出;
(3)若为其他运算符,则比较 栈顶元素 与 该优先符 优先级;
当栈顶元素优先级 >= 当前元素优先级,出栈并顺序输出栈内运算符,直到栈顶元素优先
级 < 当前元素优先级,将当前的运算符入栈。
若当前运算符优先级 > 栈顶运算符优先级, 直接入栈即可。
(4)扫描结束,顺序输出栈内元素,添至逆波兰表达式列表尾处即可。
附带实现代码:
基本定义:
private final static String OPER1 = "+"; private final static String OPER2 = "-"; private final static String OPER3 = "*"; private final static String OPER4 = "/"; private final static String OPERLEF = "("; private final static String OPERRIGHT = ")"; private String exp; private int precision = 4; // 精度计算 private RoundingMode roundingmode = RoundingMode.HALF_UP; private List<String> expList = new ArrayList<String>(); private List<String> postfixList = new ArrayList<String>();
栈的定义,不解释,见代码;
private class Stack { LinkedList<String> stackList = new LinkedList<String>(); public Stack() {} public boolean isEmpty() { return stackList.isEmpty(); } public void push(String expession) { stackList.addLast(expession); } public String pop() { return stackList.removeLast(); } public String top() { return stackList.getLast(); } }依次为判断是否是 ’)‘ ,’(‘,数字,以及优先级高低:
public boolean isNum(String str) { return str.startsWith("0")|| str.startsWith("1")|| str.startsWith("2")|| str.startsWith("3")|| str.startsWith("4")|| str.startsWith("5")|| str.startsWith("6")|| str.startsWith("7")|| str.startsWith("8")|| str.startsWith("9")|| str.startsWith("."); } /**The method using for judge whether * a char is a 'x' or a '/' * */ private boolean isHigher(String str) { if(str.equals(OPER3)||str.equals(OPER4)) { return true; } else { return false; } } /** The method using for judge whether the * priority if str1 is higher than the str2 * */ private boolean compare(String str1, String str2) { if(str1.equals(OPERLEF)) { return false; } if((!isHigher(str1))&&(isHigher(str2))) { return false; } else { if(isHigher(str1)) { return true; } else { return false; } } } /** The method using for judge the * '('*/ private boolean isLeft(String str) { return str.equals(OPERLEF); } /**The method using for judge the * ')'*/ private boolean isRight(String str) { return str.equals(OPERRIGHT); }
实现 四则运算的数字与运算符的分离,放入字符串内,后转换成后缀表达式,之后对后缀表达式进行计算。
private void seperate() { int length = exp.length(); String tempStr = ""; for(int i = 0; i < length; i++) { String tempChar = exp.substring(i,i+1); if(isNum(tempChar)) { tempStr += tempChar; } else { if(!tempStr.equals("")) { expList.add(tempStr); } expList.add(tempChar); tempStr = ""; } } if(!tempStr.equals("")) { expList.add(tempStr); } } /** The method using the expression list to * convert a poxfixExpression * return a poxfixList * */ private void convertPoxfix() { Stack stack = new Stack(); int length = expList.size(); for(int i= 0; i < length; i++) { String ch = expList.get(i); if(isNum(ch)) { postfixList.add(ch); } else { if(isLeft(ch)) { stack.push(ch); } else if(isRight(ch)) { while(!stack.isEmpty()) { String tempChar = stack.pop(); if(!tempChar.equals(OPERLEF)) { postfixList.add(tempChar); } else { break; } } } else { if(stack.isEmpty()) { stack.push(ch); } else { if(compare(stack.top(),ch)) { while(!stack.isEmpty() && compare(stack.top(),ch)) { postfixList.add(stack.pop()); } } stack.push(ch); } } } } while(!stack.isEmpty()) { postfixList.add(stack.pop()); } } /**The method using for the calculation on the decimal precision * */ public static BigDecimal getBigDecimal(String numString, int precision, RoundingMode roundingmode) { String precisionFlag = "0"; if(numString == null || numString.equals("")) { precisionFlag = "0.00"; } else { precisionFlag = numString; } BigDecimal bigdecimal = new BigDecimal(precisionFlag); bigdecimal.setScale(precision, roundingmode); return bigdecimal; } /**the method which uses the postifixExpression to calculate * the expression * return the answer which is on the top of the stack * */ public String calculation() throws ArithmeticException { Stack numStack = new Stack(); int length = postfixList.size(); for(int i = 0; i < length; i++) { String tempC = postfixList.get(i); if(isNum(tempC)) { numStack.push(tempC); } else { BigDecimal tempNum1 = getBigDecimal(numStack.pop(),precision,roundingmode); BigDecimal tempNum2 = getBigDecimal(numStack.pop(),precision,roundingmode); BigDecimal tempNum = getBigDecimal("",precision,roundingmode); if(tempC.equals(OPER1)) { tempNum = tempNum2.add(tempNum1); } else if(tempC.equals(OPER2)) { tempNum = tempNum2.subtract(tempNum1); } else if(tempC.equals(OPER3)) { tempNum = tempNum2.multiply(tempNum1); } else if(tempC.equals(OPER4)) { tempNum = tempNum2.divide(tempNum1, precision, roundingmode); } numStack.push(tempNum.toString()); } } return numStack.pop(); }类的构造:
public PostfixExp(String exp, int precision, RoundingMode roundingmode) { this.exp = exp; this.precision = precision; this.roundingmode = roundingmode; seperate(); convertPoxfix(); }
测试代码:
public String getPostfix() { String post = ""; int length = postfixList.size(); for(int i = 0; i < length; i++) { post += postfixList.get(i)+" "; } return post; }
public static void main(String[] args) { String str = "1+4/2*3+5+(3+1)+2/2"; System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); PostfixExp postfixexp = new PostfixExp(str,10,RoundingMode.HALF_UP); String post = postfixexp.getPostfix(); System.out.println("PostFix Expression: "+ post); System.out.println("Answer : "+ postfixexp.calculation()); }
至此 所有源代码已经给出,欢迎批评指正!!
部分思想源于网上大牛! 多谢各位大牛指导!!!
相关文章推荐
- Java实现表达式计算(中缀表达式转化为后缀表达式/逆波兰式)
- Java实现表达式计算(中缀表达式转化为后缀表达式/逆波兰式)
- Java实现表达式计算(中缀表达式转化为后缀表达式/逆波兰式)
- Java实现表达式计算(中缀表达式转化为后缀表达式/逆波兰式)
- Java实现表达式计算(中缀表达式转化为后缀表达式/逆波兰式)
- Java实现表达式计算(中缀表达式转化为后缀表达式/逆波兰式)
- 计算器制作JAVA版(第二步,表达式结构检查)
- 逆波兰表达式 java
- 逆波兰表达式(后缀表达式)2
- 【计算器Java实现】基于栈的复杂表达式解析&&数值计算
- 逆波兰计算器的C完整C代码(输入须为后缀表达式)
- Java解析字符串表达式--逆波兰表达式的计算
- 后缀表达式(逆波兰表达式),并求值(可求浮点、负数与大于10的数),C++实现
- Java 学习笔记---逆波兰表达式
- 逆波兰表达式(后缀表达式)
- 逆波兰计算器--中缀表达式转后缀表达式
- java 二叉树(十一)表达式与逆波兰序列
- 关于java 的科学计算算法(前,中,后缀表达式的转换)——计算器制作的心得
- Java 中缀表达式转后缀表达式 + 中/后缀表达式计算
- 逆波兰表达式 java