zoukankan      html  css  js  c++  java
  • 数学表达式与二叉树

    表达式: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;
        }

    }

     

     

  • 相关阅读:
    URLProtocol服务协议
    ODBC、OLEDB和ADO之间的关系 ,以及性能比较
    如何在VS2015查看C#界面窗体里的控件层次
    SpeechVoiceSpeakFlags枚举类型的详细解释
    SQL中遇到多条相同内容只取一条的最简单实现方法
    flink elasticsearch sink table 忽略部分字段开发
    flink elasticsearch source table 集成elasticsearch-hadoop connector开发
    记一次python 协程给合多线程死锁问题
    kubernetes gitlab runner java maven ci/cd 整体方案示例
    某云elasticsearch节点失效,手动重置primary,迁移分区
  • 原文地址:https://www.cnblogs.com/ding0910/p/2355834.html
Copyright © 2011-2022 走看看