您的位置:首页 > 其它

二叉树解析实现逆波兰公式算法

2015-06-12 16:51 288 查看
public class NiBoLan {

private static final int MAX_NODE = 100;

// 二叉树的结点类

private static class MyTreeNode {

public double value;// 若结点是数字,则保存为该结点的值;若是符号,则此字段无意义

public char symbol;// '+','-','*','/','d'

public int left;// 左孩子

public int right;// 右孩子

public int father;// 爹地

public void init() {

value = 0;

symbol = '\0';

left = -1;

right = -1;

father = -1;

}

}

private static boolean isOperator(char c) {

if (c == '+' || c == '-' || c == '*' || c == '/') {

return true;

}

return false;

}

private static boolean isDigit(char c) {

if ((c <= '9' && c >= '0') || c == '.') {

return true;

}

return false;

}

// 用递归计算树的值

private static double getNodeValue(MyTreeNode[] tree, int nodeNum)

throws Exception {

// 如果结点是数字,直接返回值

if (tree[nodeNum].symbol == 'd') {

return tree[nodeNum].value;

}

// 如果结点是符号,则递归计算

if (tree[nodeNum].symbol == '+') {

return getNodeValue(tree, tree[nodeNum].left)

+ getNodeValue(tree, tree[nodeNum].right);

}

if (tree[nodeNum].symbol == '-') {

return getNodeValue(tree, tree[nodeNum].left)

- getNodeValue(tree, tree[nodeNum].right);

}

if (tree[nodeNum].symbol == '*') {

return getNodeValue(tree, tree[nodeNum].left)

* getNodeValue(tree, tree[nodeNum].right);

}

if (tree[nodeNum].symbol == '/') {

return getNodeValue(tree, tree[nodeNum].left)

/ getNodeValue(tree, tree[nodeNum].right);

}

throw new Exception("tree error");

}

// 计算逆波兰表达式

public static double calculate(String str) {

double result = 0;

MyTreeNode tree[] = new MyTreeNode[MAX_NODE];

for (int i = 0; i < MAX_NODE; i++) {

tree[i] = new MyTreeNode();

tree[i].init();

}

int nowCount = 0;

int pointerTmp = -1;

try {

// 建立整棵二叉树

// 注意,逆波兰式解析起来应该是从右向左

for (int i = str.length() - 1; i >= 0; i--) {

if (isOperator(str.charAt(i)) || isDigit(str.charAt(i))) {

// 若是符号

if (isOperator(str.charAt(i))) {

tree[nowCount].symbol = str.charAt(i);

}

// 若是数字

else if (isDigit(str.charAt(i))) {

int numEnd = i;

while (isDigit(str.charAt(i))) {

i--;

if (i < 0) {

break;

}

}

i++;

tree[nowCount].value = Double.valueOf(str.substring(i,

numEnd + 1));

tree[nowCount].symbol = 'd';

}

// 现在开始的代码为核心+关键

// 向上找到父结点,挂载当前结点,构建二叉树

pointerTmp = nowCount - 1;

while (pointerTmp >= 0) {

// 因为数字一定在叶子结点上,因此忽略数字结点

// 优先查看找到的非叶子的右孩子,如果为空,就认其为父

if (tree[pointerTmp].right < 0

&& tree[pointerTmp].symbol != 'd') {

tree[pointerTmp].right = nowCount;

tree[nowCount].father = pointerTmp;

break;

}

// 如果右孩子非空,就看左孩子,如果为空,就认贼作父

if (tree[pointerTmp].left < 0

&& tree[pointerTmp].symbol != 'd') {

tree[pointerTmp].left = nowCount;

tree[nowCount].father = pointerTmp;

break;

}

// 如果都不为空,继续向上查找。"我要我要找我爸爸,去到哪里也要找我爸爸~~~"

pointerTmp = tree[pointerTmp].father;

}

// 如果找不到爹地,哼哼,那怎么可能!难道是无性繁殖?

if (nowCount != 0 && pointerTmp < 0) {

throw new Exception("我靠,你就不能写个正确的表达式阿");

}

nowCount++;

}

}

// 计算结果

result = getNodeValue(tree, 0);

} catch (Exception e) {

// 如果表达式错误,输出提示

System.out.println("The next expression error!");

result = 0;

}

return result;

}

public static void main(String[] args) {

String str = "1 2 3 4 5*-6 + -*";

String str2 = "1.23 252.6 3 4.8 5* - * 6 + *";

String str3 = "1.23 252.6 3 4.8 5* - * 6 ++ *";// 这个表达式是错的,输出错误提示

String str4 = "1.23 252.6 3 4.8 5";// 这个表达式还是错的,输出错误提示

System.out.println(str + " = " + calculate(str));

System.out.println(str2 + " = " + calculate(str2));

System.out.println(str3 + " = " + calculate(str3));

System.out.println(str4 + " = " + calculate(str4));

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: