trie树的实现和应用及测试

来源:互联网 发布:淘宝网经验 编辑:程序博客网 时间:2024/06/05 20:51
测试输出为:
按字典顺序输出trie树中所有的字符串 递归实现: abc abc abcd aca adac ava bda按字典顺序输出trie树中所有的字符串 迭代实现: abc abc abcd aca adac ava bda是否出现字符串ava:true前缀a出现的次数:6输出还有前缀的ab的所有字符串:abcabcabcdProcess finished with exit code 0
java代码如下:
package com.liyiwen.TestTrie;import javax.swing.tree.TreeNode;import java.util.Stack;/** * @author liyiwen1 * @date 2016/12/5 *///trie树可以以非常少的,存储大量具有很多相同前缀的字符串。trie树查询比哈希表快,public class Trie {    public static void main(String[] args) {        String[] strings = new String[]{"ava", "aca", "bda", "adac", "abc","abcd", "abc"};        Trie trie = Trie.getInstance();        for (String string : strings){            trie.insert(string);        }        System.out.println("按字典顺序输出trie树中所有的字符串 递归实现:");        trie.printAllString();        System.out.println("按字典顺序输出trie树中所有的字符串 迭代实现:");        trie.printAllStringIteration();        System.out.println("是否出现字符串ava:" + trie.hasString("ava"));        System.out.println("前缀a出现的次数:" + trie.preCount("a"));        System.out.println("输出还有前缀的ab的所有字符串:");        trie.printAllStrsContainsPre("ab");    }    private int size = 26;    private TrieNode root;    private Trie() {        root = new TrieNode();    }    public static Trie getInstance() {        return new Trie();    }    public void insert(String str) {        if (null == str || str.isEmpty()) {            return;        }        TrieNode node = root;        char[] charArray = str.toCharArray();        for (char val : charArray) {            int index = val - 'a';            if (null == node.nodes[index]) {                node.nodes[index] = new TrieNode();                node.nodes[index].val = val;            } else {                node.nodes[index].passCount++;            }            node = node.nodes[index];        }        node.isEnd++;    }    //判断是否出现字符串extStr    public boolean hasString(String extStr) {        if (null == extStr || extStr.isEmpty()) return false;        char[] chars = extStr.toCharArray();        TrieNode node = root;        for (char val : chars) {            int index = val - 'a';            if (null == node.nodes[index]) {                return false;            } else {                node = node.nodes[index];            }        }        return node.isEnd != 0;    }    //计算前缀出现的次数    public int preCount(String pex) {        if (null == pex || pex.isEmpty()) return 0;        TrieNode node = root;        char[] chars = pex.toCharArray();        for (char val : chars) {            int index = val - 'a';            if (null == node.nodes[index]) {                return 0;            } else {                node = node.nodes[index];            }        }        return node.passCount;    }    //输出所有的字符串,按字典顺序    public void printAllString(){        printAllString(getRoot(), "");    }    //输出所有的字符串,按字典顺序, 迭代实现    public void printAllStringIteration(){        printAllStringIteration(getRoot(), "");    }    //输入以node为根节点的树所包含的所有字符串,pre为前缀    private void printAllString(TrieNode node, String pre){        if (node == null){            return ;        }        pre = pre + node.val;        if (node.isEnd != 0){            for (int i = 0; i < node.isEnd; i++){                System.out.println(pre);            }        }        for (TrieNode node1 : node.nodes){            printAllString(node1, pre);        }    }    private static class Pair{        private TrieNode node;        private String pre;        public TrieNode getNode() {            return node;        }        public void setNode(TrieNode node) {            this.node = node;        }        public String getPre() {            return pre;        }        public void setPre(String pre) {            this.pre = pre;        }        public Pair(TrieNode node, String pre) {            this.node = node;            this.pre = pre;        }    }    //输出含有pre前缀的所有字符串    public void printAllStrsContainsPre(String pre){        TrieNode node = getRoot();        for (char c : pre.toCharArray()){            int index = c - 'a';            if (node.nodes[index] == null){                return;            }else{                node = node.nodes[index];            }        }        for (TrieNode node1 : node.nodes){            if (node1  != null){                printAllString(node1, pre);            }        }    }    //输入以node为根节点的树所包含的所有字符串,pre为前缀, 迭代实现    private void printAllStringIteration(TrieNode node, String pre){        Stack<Pair> stack = new Stack<Pair>();        stack.push(new Pair(node, pre));        while (!stack.isEmpty()){            Pair pair = stack.pop();            node = pair.node;            pre = pair.pre;            if (node != null){                pre = pre + node.val;                if (node.isEnd != 0){                    for (int i = 0; i < node.isEnd; i++){                        System.out.println(pre);                    }                }                for (int i = node.nodes.length - 1; i >= 0; i--){                    stack.push(new Pair(node.nodes[i], pre));                }            }        }    }    //前序遍历Trie树    public void preOrderTraverse() {        preOrderTraverse(getRoot());    }    private void preOrderTraverse(TrieNode node) {        if (node != null) {            System.out.print(node.val + "-");            for (TrieNode sonNode : node.nodes) {                preOrderTraverse(sonNode);            }        }    }    private TrieNode getRoot() {        return root;    }    private class TrieNode {        private int passCount;        private int isEnd;        private TrieNode[] nodes;        private char val;        public TrieNode() {            passCount = 1;            isEnd = 0;            nodes = new TrieNode[size];        }    }}
0 0
原创粉丝点击