您的位置:首页 > 其它

二叉树计算四则运算表达式

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 )

以此类推,得到整棵二插运算树。

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;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  string null class tree c