数学表达式与二叉树

表达式:a*(b+c/d)+c*h-g*f表示如下的树。

 

View Code
package com.jstrd.base.commons.util;

import java.util.ArrayList;
import java.util.Stack;

import com.jstrd.util.StringUtil;

public class Test {

    public static void main(String[] args) {
        String s = "3+abs(5+1*2)";
        //为了生成波兰表达式,对单目运算符先做转换处理,例将abs(a+b)替换成(abs:a+b),其中冒号“:”做为一种特殊的双目运算符
        for (int i = 0; i < unaryOperator.length; i++) {
            s = s.replaceAll(unaryOperator[i] + "\\(", "\\(" + unaryOperator[i] + "\\:");
        }
        TNode tree = (new Test()).parseAF2Tree(s);
        (new BinaryTree()).printTree(tree, 0);
        System.out.println("");
    }
    private final static String[] unaryOperator = {"abs", "sqrt"};
    private final static String[] binaryOperator = {":", "+", "-", "*", "/", "(", ")"};

    /**
     * 将一个数学算式转化为一个树
     * 
     * 
@param s
     *            此算式的字符串
     
*/
    public TNode parseAF2Tree(String s) {
        Stack<String> sta = new Stack<String>();
        sta.push("#");
//        char[] ch = new char[s.length() + 1];
        ArrayList<String> ch = new ArrayList<String>();
//        int j = 0;
        
// 将中序表达式转化为逆波兰表达式
        String character = "";
        for (int i = 0; i < s.length(); i++) {
            char cha = s.charAt(i);
            if (!StringUtil.exists(String.valueOf(cha), binaryOperator)) {
                character += String.valueOf(cha);
                if ((i + 1) < s.length() && !StringUtil.exists(String.valueOf(s.charAt(i+1)), binaryOperator)) {
                    continue;
                } else {
                    ch.add(character);
                    character = "";
                }
//                ch[j++] = cha;
            } else if (cha == '(') {
                sta.push(String.valueOf(cha));
            } else if (cha == ')') {
                String c = sta.pop();
                while (!c.equals("(")) {
//                    ch[j++] = c;
                    ch.add(c);
                    c = sta.pop();
                }
            } else {
                String c = sta.peek();
                while (c.equals("*") || c.equals("/")) {
                    //ch[j++] = sta.pop();
                    ch.add(sta.pop());
                    c = sta.peek();
                }
                sta.push(String.valueOf(cha));
            }
        }
        String c = sta.pop();
        while (!c.equals("#")) {
//            ch[j++] = c;
            ch.add(c);
            c = sta.pop();
        }
        // 将逆波兰转化为波兰表达式
        Object[] chArr = ch.toArray();
        int j = chArr.length;
        String[] temp = new String[j + 1];
        for (int i = 0; i < j; i++) {
            temp[j - i - 1] = chArr[i].toString();
        }
        temp[j] = "#";
        // 由波兰表达式建树
        TNode root = creatAFTree(temp);
        return root;
    }

    /**
     * 将波兰表达式建成一棵树
     * 
     * 
@param ch
     * 
@param key
     * 
@return
     
*/
    public TNode creatAFTree(String[] ch) {
        TNode current = null;
        if (!ch[key].equals("#")) {
            if (StringUtil.exists(ch[key], binaryOperator)) {
                current = new TNode(ch[key++]);
                TNode temp = creatAFTree(ch);
                if (temp == null) {
                } else {
                    current.setRight(temp);
                    temp.setParent(current);
                }
                TNode temp2 = creatAFTree(ch);
                if (temp2 == null) {
                } else {
                    current.setLeft(temp2);
                    temp2.setParent(current);
                }
                return current;
            } else {
                current = new TNode(ch[key++]);
                return current;
            }
        } else {
            return null;
        }
    }

    private int key = 0;
}

class TNode {

    //1常量,2变量,3运算函数,4双目运算符,5单目运算符
    private int nodeType; 
    private Object obj;
    private TNode parent;
    private TNode left;
    private TNode right;
    
    public int getNodeType() {
        return nodeType;
    }

    public void setNodeType(int nodeType) {
        this.nodeType = nodeType;
    }

    public TNode(Object obj) {
        this.obj = obj;
    }

    public TNode() {
    }

    public Object getObj() {
        return obj;
    }

    public void setObj(Object obj) {
        this.obj = obj;
    }

    public TNode getParent() {
        return parent;
    }

    public void setParent(TNode parent) {
        this.parent = parent;
    }

    public TNode getLeft() {
        return left;
    }

    public void setLeft(TNode left) {
        this.left = left;
    }

    public TNode getRight() {
        return right;
    }

    public void setRight(TNode right) {
        this.right = right;
    }
}

class BinaryTree {

    private static TNode root;

    public BinaryTree() {

    }

    /**
     * 重写二叉树的构造方法
     * 
     * 
@param obj
     
*/
    public BinaryTree(Object obj) {
        root = new TNode(obj);
    }

    /**
     * 将整型数组转化为一棵二叉查找树
     * 
     * 
@param Array
     *            待转化的数组
     
*/
    public void ArraytoTree(int[] Array) {
        if (Array.length == 0) {
            throw new RuntimeException("数组长度为0,没有元素用来建树!");
        }
        int first = Array[0];
        root = new TNode(first);
        for (int i = 1; i < Array.length; i++) {
            addofBST(root, Array[i]);
        }
    }

    /**
     * 将一个数以二叉查找树的顺序插入树中
     * 
     * 
@param node
     * 
@param value
     
*/
    public void addofBST(TNode node, int value) {
        TNode current;
        if ((Integer) node.getObj() >= value) {
            if (node.getLeft() != null) {
                current = node.getLeft();
                addofBST(current, value);
            } else {
                current = new TNode(value);
                current.setParent(node);
                node.setLeft(current);
            }
        } else {
            if (node.getRight() != null) {
                current = node.getRight();
                addofBST(current, value);
            } else {
                current = new TNode(value);
                current.setParent(node);
                node.setRight(current);
            }
        }
    }

    /**
     * 以选定模式遍历打印二叉树
     * 
     * 
@param node
     *            二叉树起始结点
     * 
@param style
     *            模式,1为中左右,0为左中右,-1为左右中
     
*/
    public void printTree(TNode node, int style) {
        if (node != null) {
            if (style == 1) {
                // 打印此结点
                Object obj = node.getObj();
                System.out.println(obj);
                // 得到它的左子结点,并递归
                TNode left = node.getLeft();
                printTree(left, style);
                // 得到它的右子结点,并递归
                TNode right = node.getRight();
                printTree(right, style);
            } else if (style == 0) {
                Object obj = node.getObj();
                // 得到它的左子结点,并递归
                TNode left = node.getLeft();
                if (null != left
                        && null != node.getParent()
                        && this.getOperatorLevel(obj.toString()) < this
                                .getOperatorLevel(node.getParent().getObj()
                                        .toString()))
                    System.out.print("(");
                printTree(left, style);
                // 打印此结点
                System.out.print(obj);
                // 得到它的右子结点,并递归
                TNode right = node.getRight();
                printTree(right, style);
                if (null != right
                        && null != node.getParent()
                        && this.getOperatorLevel(obj.toString()) < this
                                .getOperatorLevel(node.getParent().getObj()
                                        .toString()))
                    System.out.print(")");
            } else if (style == -1) {
                // 得到它的左子结点,并递归
                TNode left = node.getLeft();
                printTree(left, style);
                // 得到它的右子结点,并递归
                TNode right = node.getRight();
                printTree(right, style);
                // 打印此结点
                Object obj = node.getObj();
                System.out.println(obj);
            }
        }
    }

    private int getOperatorLevel(String operator) {
        if (StringUtil.exists(operator, new String[] { "+", "-" })) {
            return 1;
        }
        if (StringUtil.exists(operator, new String[] { "*", "/" })) {
            return 2;
        }
        return 0;
    }

}

 

 

 

 

 

 

 

posted @ 2012-02-17 15:03  blueKnight  Views(...)  Comments(... Edit 收藏