单词查找树

单词查找树(Trie 树/字典树)可以用于存储大量的字符串以便支持快速模式匹配,主要应用在信息检索领域。
大作业要求分析几百万条密码结构,其中包含对英文单词及中文拼音密码的统计,经过查阅资料,发现Trie树能有效解决单词匹配问题。
问题解决分为两部分:Trie树生成;单词匹配
(1)Trie树生成
对于每一个节点,从根遍历到他的过程就是一个单词,如果这个节点被标记为红色,就表示这个单词存在,否则不存在。
那么,对于一个单词,我只要顺着他从根走到对应的节点,再看这个节点是否被标记为红色就可以知道它是否出现过了。把这个节点标记为红色,就相当于插入了这个单词。图示及参考代码如下:http://jaychang.iteye.com/blog/1559610

class Trie {  
    /** 定义单词查找树根节点,根节点为一个空的节点 */  
    private Vertex root = new Vertex();  

    /** 单词查找树的节点(内部类) */  
    private class Vertex {  

        /** 单词出现次数统计 */  
        int wordCount;  
        /** 以某个前缀开头的单词,它的出现次数 */  
        int prefixCount;  
        /** 当前节点的子节点用数组表示 */  
        Vertex[] vertexs = new Vertex[26];  

        /** 
         * 树节点的构造函数 
         */  
        public Vertex() {  
            wordCount = 0;  
            prefixCount = 0;  
        }  
    }  

    /** 
     * 单词查找树构造函数 
     */  
    public Trie() {  

    }  

    /** 
     * 向单词查找树添加一个新单词 
     */  
    public void addWord(String word) {  
        addWord(root, word.toLowerCase());  //每次插入都从根节点开始找,单词转小写
    }  

    /** 
     * 向单词查找树添加一个新单词 
     * @param root 单词查找树节点           
     * @param word 单词          
     */  
    private void addWord(Vertex vertex, String word) {  
        if (word.length() == 0) {   
        } else if (word.length() > 0) {  
          vertex.prefixCount++; //此前缀出现次数+1
            char c = word.charAt(0);  //得到当前字符串的首字母
            int index = c - 'a';  //将首字母与‘a’的ASCII码相减即可知道此首字母位于26位数组的哪一位
            //如果当前结点的此子节点为空,说明从未出现过此前缀序列,则new一个结点代表这个位置有字母
            if (null == vertex.vertexs[index])                    
            {
                vertex.vertexs[index] = new Vertex();  
            }  
            //从此子节点开始继续向下查找插入。word.substring(1)表示除去当前序列的第一个字母 
            addWord(vertex.vertexs[index], word.substring(1));                                                          
        }  
    }  
 }
 /** 
     * 测试片段 
     */  
public class Main {  
    public static void main(String[] args) {  
        Trie trie = new Trie();  //初始化一棵Trie树
        trie.addWord("abc");  //插入单词
        trie.addWord("abcd");  
        trie.addWord("abcde");  
        trie.addWord("abcdef"); 
    }  
}  

(2)Trie树匹配
单词匹配即在已有的Trie树基础上检验单词是否存在于此字典中。如果有,返回至此为止出现次数。没有返回0.

    /** 
     * 统计某个单词出现次数 
     * @param word  单词 
     * @return 出现次数 
     */  
    public int countWord(String word) {  
        return countWord(root, word);  
    }  

    /** 
     * 每次都从根节点开始查找 
     */  
    private int countWord(Vertex vertex, String word) {  
        if (word.length() == 0) {  //一直查找到字符串结束,说明单词查找成功,返回
            vertex.wordCount++; 
            return vertex.wordCount;  
        } else {  
            char c = word.charAt(0);  
            int index = c - 'a';  
            //如果字符串还未结束但当前结点无此子节点,说明这个序列不存在于字典中,单词查找失败                                               
            if (null == vertex.vertexs[index]) {  
                return 0;  
            } else {  
                return countWord(vertex.vertexs[index], word.substring(1));  
            }  
        }  
    }  

特别的:
 /** 
     * 统计字典中以某个前缀开始的单词,它的出现次数(前缀本身不算在内)  
     * @param word  前缀 
     * @return 出现次数 
     */  
    public int countPrefix(String word) {  
        return countPrefix(root, word);  
    }  

    private int countPrefix(Vertex vertex, String prefixSegment) {  
        if (prefixSegment.length() == 0) {  
            return vertex.prefixCount;  
        } else {  
            char c = prefixSegment.charAt(0);  
            int index = c - 'a';  
            if (null == vertex.vertexs[index]) {  
                return 0;  
            } else {  
                return countPrefix(vertex.vertexs[index], prefixSegment.substring(1));  
            }  
        }  
    }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值