二叉树计算四则运算表达式
2012-07-09 20:02
363 查看
转自:http://blog.csdn.net/a477997/article/details/7369151
1 * 2 / ( ( 3 + 4 ) * ( - 5 + 6 ) )
这样一个式子,采用二叉树实现四则运算,需要使用递归的思想。总共分两步,第一步是建立二叉树,第二步是计算。
建立二叉树:
将式子存入一个char[] expresstion中,然后带入一个消除多余括号的函数TrimOutParenthes(消除括号,例如(1 * 2 / ( ( 3 + 4 ) * ( - 5+ 6 ) ))的最外层括号,主要用于消除分支节点中的括号,例如( 3 + 4 )),然后从右向左扫描每一个元素,找到最外层(括号外的)中最左边的符号,将该符号(例如式子中的*)作为父节点,将符号两边的式子作为子节点。如下:
*
1 2/ ( ( 3 + 4 ) * ( - 5 + 6 ) )
然后递归计算这两个子节点,也就是作为表达式再次代入。
2 / ( ( 3 + 4 ) * ( - 5 + 6 ) )的计算结果是:
/
2 (( 3 + 4 ) * ( - 5 + 6 ) )
于是目前的结果就是
*
1 /
2 ( 3 + 4 ) * ( - 5 + 6 )
以此类推,得到整棵二插运算树。
1 * 2 / ( ( 3 + 4 ) * ( - 5 + 6 ) )
这样一个式子,采用二叉树实现四则运算,需要使用递归的思想。总共分两步,第一步是建立二叉树,第二步是计算。
建立二叉树:
将式子存入一个char[] expresstion中,然后带入一个消除多余括号的函数TrimOutParenthes(消除括号,例如(1 * 2 / ( ( 3 + 4 ) * ( - 5+ 6 ) ))的最外层括号,主要用于消除分支节点中的括号,例如( 3 + 4 )),然后从右向左扫描每一个元素,找到最外层(括号外的)中最左边的符号,将该符号(例如式子中的*)作为父节点,将符号两边的式子作为子节点。如下:
*
1 2/ ( ( 3 + 4 ) * ( - 5 + 6 ) )
然后递归计算这两个子节点,也就是作为表达式再次代入。
2 / ( ( 3 + 4 ) * ( - 5 + 6 ) )的计算结果是:
/
2 (( 3 + 4 ) * ( - 5 + 6 ) )
于是目前的结果就是
*
1 /
2 ( 3 + 4 ) * ( - 5 + 6 )
以此类推,得到整棵二插运算树。
package com.zeph.calculator; public class Calculator { /** * @param args * @author JiangQifan * @since 2012/3/19 */ public static void main(String[] args) { // TODO Auto-generated method stub Calculator ca = new Calculator(); ca.calculator(); } public void calculator() { double a = new TreeNode("1+2+(3+4)+5+6").calculate(); System.out.println(a); } class TreeNode { double data; char operation; TreeNode left; TreeNode right; /* * recursively construct the tree */ public TreeNode(String expression) { char[] exc = toCharArrayTrimOutParenthes(expression); if (exc == null) { return; } exc = syntaxCheck(exc); int length = exc.length; int index = 0; if (hasOperation(exc)) { int parenthes = 0; for (int i = length - 1; i >= 0; i--) { if (exc[i] == '(') { parenthes--; } else if (exc[i] == ')') { parenthes++; } if (parenthes > 0) { continue; } if (exc[i] == '*' || exc[i] == '/') { index = i; } else if (exc[i] == '+' || exc[i] == '-') { index = i; break; } } if (isOperation(exc[index])) { operation = exc[index]; } StringBuilder sbleft = new StringBuilder(); StringBuilder sbright = new StringBuilder(); for (int i = 0; i < index; i++) { sbleft.append(exc[i]); } for (int i = index + 1; i < length; i++) { sbright.append(exc[i]); } left = new TreeNode(sbleft.toString()); right = new TreeNode(sbright.toString()); } else { StringBuilder value = new StringBuilder(); value.append(exc); data = Double.parseDouble(value.toString()); } } /* * check the expression's syntax if there is two or more continuous * operations,print out syntax error add '0' before the '-' if it's a * negative */ public char[] syntaxCheck(char[] cArray) { boolean flag = false; if (isOperation(cArray[0])) { char[] checkedArray = new char[cArray.length + 1]; checkedArray[0] = '0'; for (int i = 0; i < cArray.length; i++) { checkedArray[i + 1] = cArray[i]; } cArray = checkedArray; } for (int i = 0; i < cArray.length; i++) { if (isOperation(cArray[i])) { if (flag == true) { System.out.println("syntaxError"); } flag = true; } else { flag = false; } } return cArray; } /* * is there operations in the char array if there is,return true. if * not,return false */ public boolean hasOperation(char[] cArray) { for (int i = 0; i < cArray.length; i++) { if (isOperation(cArray[i])) { return true; } } return false; } public boolean isOperation(char c) { return (c == '+' || c == '-' || c == '*' || c == '/'); } /* * trim the out most useless parentheses and return a char array */ public char[] toCharArrayTrimOutParenthes(String src) { if (src.length() == 0) { return null; } String result = src; while (result.charAt(0) == '(' && result.charAt(result.length() - 1) == ')') { int parenthes = 0; for (int i = 0; i < result.length() - 1; i++) { if (result.charAt(i) == '(') { parenthes++; } else if (result.charAt(i) == ')') { parenthes--; } if (parenthes == 0) { return result.toCharArray(); } } result = result.substring(1, result.length() - 1); } return result.toCharArray(); } // recursively calculate public double calculate() { double result = 0; if (left == null && right == null) { result = data; } else { double leftResult = left.calculate(); double rightResult = right.calculate(); switch (operation) { case '+': result = leftResult + rightResult; break; case '-': result = leftResult - rightResult; break; case '*': result = leftResult * rightResult; break; case '/': result = leftResult / rightResult; break; default: break; } } return result; } } }
相关文章推荐
- 用二叉树存储计算四则运算表达式
- 字符串四则运算表达式的计算(华为机试)
- 表达式(四则运算)计算的算法代写 essay代写
- java中正则表达式用Pattern计算字符串的结果(四则运算);分成有括号和没括号;当然也可以采用逆波兰式
- IDG | 四则运算表达式计算
- 字符串四则运算表达式的计算(华为机试)
- 计算表达式的值(仅含有四则运算和支持括号嵌套,浮点数运算)
- 用PHP实现的四则运算表达式计算
- 如何处理加括号的四则混合运算表达式——基于二叉树的实现(Eclipse平台 Java版)
- 一个计算四则运算表达式文本的方法
- Java实现四则运算表达式计算
- 计算带括号的四则运算表达式,这个实现方式你想过吗?
- 【原创】Delphi实现数学表达式的计算(逆波兰式法)-四则运算解析
- 表达式计算 四则运算(有括号)的计算
- java 解析四则混合运算表达式并计算结果
- 中缀表达式的计算(只包含四则运算与括号)
- 计算一个字符串表示的四则运算表达式
- 字符串四则运算表达式的计算(华为机试)
- C语言实现整数四则运算表达式的计算
- 表达式(四则运算)计算的算法