⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hierarchypropertyparser.java

📁 一个数据挖掘软件ALPHAMINERR的整个过程的JAVA版源代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 *    This program is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; either version 2 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/*
 *    HierarchyPropertyParser.java
 *    Copyright (C) 2001 Xin Xu
 *
 */

package weka.gui;

import java.io.Serializable;
import java.util.StringTokenizer;
import java.util.Vector;


/**
 * This class implements a parser to read properties that have
 * a hierarchy(i.e. tree) structure.  Conceptually it's similar to 
 * the XML DOM/SAX parser but of course is much simpler and 
 * uses dot as the seperator of levels instead of back-slash.<br>
 * It provides interfaces to both build a parser tree and traverse
 * the tree. <br>
 * Note that this implementation does not lock the tree when different
 * threads are traversing it simultaneously, i.e. it's NOT synchronized
 * and multi-thread safe.  It is recommended that later implementation
 * extending this class provide a locking scheme and override the 
 * functions with the "synchronized" modifier (most of them are 
 * goToXXX() and information accessing functions).<p>
 *
 * @author Xin Xu (xx5@cs.waikato.ac.nz)
 * @version $Revision$
 */
public class HierarchyPropertyParser implements Serializable{

    /** Keep track of the root of the tree */
    private TreeNode m_Root;
    
    /** Keep track of the current node when traversing the tree */
    private TreeNode m_Current;

    /** The level separate in the path */
    private String m_Seperator = ".";
    
    /** The depth of the tree */
    private int m_Depth = 0;
	
    /** 
     * The inner class implementing a single tree node.
     * All fields are made public simply for convenient access,
     * Although a severe violation of OO Design principle.
     */
    private class TreeNode{
	/** The parent of this node */
	public TreeNode parent = null;
	
	/** The value of this node.  Always String  */
	public String value = null;

	/** The children of this node */
	public Vector children = null;	

	/** The level of this node */
	public int level = 0;

	/** The context of this node */
	public String context = null;
    }
    
    /** Default constructor */
    public HierarchyPropertyParser(){
	m_Root = new TreeNode();
	m_Root.parent = null;
	m_Root.children = new Vector();
	goToRoot();
    }
    
    /**
     * Constructor that builds a tree from the given property with
     * the given delimitor
     *
     * @param p the given property string
     * @param delim the given dilimitor
     */
    public HierarchyPropertyParser(String p, String delim) throws Exception {
	this();		
	build(p, delim);
    }
    
    /**
     * Set the seperator between levels.  Default is dot.
     *
     * @param s the seperator symbol
     */
    public void setSeperator(String s){
	m_Seperator = s;
    }

    /**
     * Get the seperator between levels.  Default is dot.
     *
     * @return the seperator symbol
     */
    public String getSeperator(){ return m_Seperator; }
   
    /** 
     * Build a tree from the given property with the given delimitor
     *
     * @param p the given property
     * @param delim the given delimitor
     */
    public void build(String p, String delim) throws Exception {
	StringTokenizer st = new StringTokenizer(p, delim);
	//System.err.println("delim: "+delim);
	while(st.hasMoreTokens()){
	    String property = st.nextToken().trim();
	    if(!isHierachic(property))
		throw new Exception("The given property is not in"+
				    "hierachy structure with seperators!");
	    add(property);	   
	}
	goToRoot();
    }

    /**
     * Add the given item of property to the tree
     *
     * @param property the given item
     */ 
    public synchronized void add(String property){
	String[] values = tokenize(property);
	if(m_Root.value == null)
	    m_Root.value = values[0];
	
	buildBranch(m_Root, values, 1);
    }
    
    /** 
     * Private function to build one branch of the tree
     * based on one property 
     * 
     * @param parent the parent of the node to be built
     * @param values the value of one property
     * @param lvl the level of the node to be built in the tree
     */
    private void buildBranch(TreeNode parent, String[] values, int lvl){
	// Precondition: children is not null
	
	if(lvl == values.length){  // Parent is leaf
	    parent.children = null;
	    return;
	}
	
	if(lvl > (m_Depth-1))
	    m_Depth = lvl+1;  // Depth starts from 1
	
	Vector kids = parent.children;
	int index = search(kids, values[lvl]);
	if(index != -1){
	    TreeNode newParent = (TreeNode)kids.elementAt(index);
	    if(newParent.children == null)
		newParent.children = new Vector();
	    buildBranch(newParent, values, lvl+1);
	}
	else{
	    TreeNode added = new TreeNode();
	    added.parent = parent;
	    added.value = values[lvl];
	    added.children = new Vector();
	    added.level = lvl;
	    if(parent != m_Root)
		added.context = parent.context + m_Seperator + parent.value;
	    else
		added.context = parent.value;
	    
	    kids.addElement(added);
	    buildBranch(added, values, lvl+1);
	}
    }
    
    /**
     * Tokenize the given string based on the seperator and
     * put the tokens into an array of strings
     *
     * @param rawString the given string
     * @return an array of strings
     */
    public String[] tokenize(String rawString){
	Vector result = new Vector();
	StringTokenizer tk = new StringTokenizer(rawString, m_Seperator);
	while(tk.hasMoreTokens())
	    result.addElement(tk.nextToken());
	
	String[] newStrings = new String[result.size()];
	for(int i=0; i < result.size(); i++)
	    newStrings[i] = (String)result.elementAt(i);
	
	return newStrings;
    }
    
    /**
     * Whether the HierarchyPropertyParser contains the given
     * string
     *
     * @param string the given string
     * @return whether contains
     */
    public boolean contains(String string){
	String[] item = tokenize(string);
	if(!item[0].equals(m_Root.value))
	    return false;
	
	return isContained(m_Root, item, 1);
    }
    
    /** 
     * Private function to decide whether one level of one branch 
     * contains the relevant values
     * 
     * @param parent the parent of the node to be searched
     * @param values the value of one property
     * @param lvl the level of the node in question
     * @return whether this branch contains the corresponding values
     */
    private boolean isContained(TreeNode parent, String[] values, int lvl){
	if(lvl == values.length)  // Parent is leaf
	    return true;
	else if(lvl > values.length)
	    return false;
	else{
	    Vector kids = parent.children;
	    int index = search(kids, values[lvl]);
	    if(index != -1){
		TreeNode newParent = (TreeNode)kids.elementAt(index);
		return isContained(newParent, values, lvl+1);
	    }
	    else
		return false;
	}
    }
    
    /** 
     * Whether the given string has a hierachy structure with
     * the seperators
     *
     * @param string the given string
     */
    public boolean isHierachic(String string){
	int index = string.indexOf(m_Seperator); 
	// Seperator not occur or first occurance at the end
	if((index == (string.length()-1)) || (index == -1))
	    return false;
	
	return true;
    }

    /**
     * Helper function to search for the given target string in a 
     * given vector in which the elements' value may hopefully is equal
     * to the target.  If such elements are found the first index
     * is returned, otherwise -1
     *
     * @param vct the given vector
     * @param target the given target string
     * @return the index of the found element, -1 if not found
     */
    public int search(Vector vct, String target){
	if(vct == null)
	    return -1;
	
	for(int i=0; i < vct.size(); i++)
	    if(target.equals(((TreeNode)vct.elementAt(i)).value))
		return i;
	
	return -1;
    }

    /**
     * Go to a certain node of the tree according to the specified path
     * Note that the path must be absolute path from the root.  <br>
     * For relative path, see goDown(String path).
     *
     * @param path the given absolute path
     * @return whether the path exists, if false the current position does
     * not move
     */
    public synchronized boolean goTo(String path){
	if(!isHierachic(path)){
	    if(m_Root.value.equals(path)){
		goToRoot();
		return true;
	    }
	    else
		return false;
	}
	
	TreeNode old = m_Current;
	m_Current = new TreeNode(); 
	goToRoot();
	String[] nodes = tokenize(path);
	if(!m_Current.value.equals(nodes[0]))
	    return false;

	for(int i=1; i < nodes.length; i++){
	    int pos = search(m_Current.children, nodes[i]);
	    if(pos == -1){
		m_Current = old;
		return false;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -