惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Security Archives - TechRepublic
Security Archives - TechRepublic
Project Zero
Project Zero
K
Kaspersky official blog
G
Google Developers Blog
T
Threat Research - Cisco Blogs
T
The Blog of Author Tim Ferriss
Cyberwarzone
Cyberwarzone
Y
Y Combinator Blog
Recorded Future
Recorded Future
Blog — PlanetScale
Blog — PlanetScale
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Cisco Talos Blog
Cisco Talos Blog
Latest news
Latest news
Microsoft Security Blog
Microsoft Security Blog
H
Help Net Security
S
Schneier on Security
P
Palo Alto Networks Blog
H
Hacker News: Front Page
N
News and Events Feed by Topic
N
Netflix TechBlog - Medium
博客园 - Franky
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
SecWiki News
SecWiki News
Cloudbric
Cloudbric
TaoSecurity Blog
TaoSecurity Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
The Hacker News
The Hacker News
C
Check Point Blog
L
LangChain Blog
腾讯CDC
小众软件
小众软件
T
Tenable Blog
Google DeepMind News
Google DeepMind News
GbyAI
GbyAI
L
LINUX DO - 最新话题
A
About on SuperTechFans
Google Online Security Blog
Google Online Security Blog
C
Cisco Blogs
Recent Announcements
Recent Announcements
Hacker News: Ask HN
Hacker News: Ask HN
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Vercel News
Vercel News
雷峰网
雷峰网
美团技术团队
D
DataBreaches.Net
Martin Fowler
Martin Fowler
Help Net Security
Help Net Security
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
F
Full Disclosure
博客园_首页

博客园 - blueKnight

Java根据WSDL生成request的SOAP报文模板 【转】HttpClient使用Post和Get提交参数 Java解析Soap XML HttpClient示例 【转】C++标准库和标准模板库 dotNetFrameWork 3.5SP1离线安装 笔记本电脑win7创建WIFI热点 【转】Oracle免客户端For .Net(增加分析Devart和DataDirect) 【转】ORA-00257 archiver error. 错误的处理方法 FIREFOX不支持font-family: webdings;怎么办? "5","6"排序上下箭头问题 【转】Eclipse插件开发之基础篇(1) 插件开发的基础知识 http MIME大全 在iframe里的页面编写js,实现在父窗口上创建动画效果展开和收缩的div(不变动iframe父窗口代码) FreeMarker示例 转:用XML编写EXCEL文件 【网摘】BI系统(Business Intelligence) js获取周.html 关于j2ee工程发布到was上后,部分更新,例修改web.xml配置文件不起作用的原因解析 SSI(Struts2+Spring2+IBatis)代码生成器(纯Java版)
数学表达式与二叉树
blueKnight · 2012-02-17 · via 博客园 - blueKnight

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

}