在Java中实现Trie

时间:2017-03-25 02:25:39

标签: java data-structures trie

这是我对Trie的实现。

public class Trie {

    private class Node{
        private Map<Character, Node> children;
        boolean end;

        public Node(){
            children = new HashMap<>();
            end = false;
        }
    }

    private Node root;

    public Trie(){
        root = new Node();
    }

    public void insert(String word){
        Node current = root;
        for (int i=0; i < word.length(); i++){
            char c = word.charAt(i);
            Node node = current.children.get(c);
            if(node == null){
                node = new Node();
                current.children.put(c, node);
            }
            current = node;
        }
    }

    public boolean search(String word){
        Node current = root;
        for(int i =0; i < word.length(); i++){
            char c = word.charAt(i);
            Node node = current.children.get(c);
            if(node == null) 
                return false;
            current = node;
        }
        return current.end;
    }
}

我想添加一个方法,给定一个字符串返回其所有子节点,这可以用作真实世界的自动更正建议。

这是方法签名:

public List<String> returnAllChildren(String str){

}

我对这个有点失落。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:2)

首先,当您插入节点时,您应该在尾节点设置end = true。然后在Trie中查找前缀时,您只需要在前缀中找到最后一个字符的节点,然后递归获取所有字符串。这是一个可以帮助你的例子:

public class Trie {

private class Node{
    private Map<Character, Node> children;
    boolean end;

    public Node(){
        children = new HashMap<>();
        end = false;
    }
}

private Node root;

public Trie(){
    root = new Node();
}

public void insert(String word){
    Node current = root;
    for (int i=0; i < word.length(); i++){
        char c = word.charAt(i);
        Node node = current.children.get(c);
        if(node == null){
            node = new Node();
            current.children.put(c, node);
        }
        current = node;
    }
    // Set end to true
    current.end = true;
}

public boolean search(String word){
    Node current = root;
    for(int i =0; i < word.length(); i++){
        char c = word.charAt(i);
        Node node = current.children.get(c);
        if(node == null)
            return false;
        current = node;
    }
    return current.end;
}


private List<String> getAll(String prefix, Node node) {
    List<String> r = new ArrayList<>();
    if (node.end) {
        r.add(prefix);
    }
    for (Map.Entry<Character, Node> child : node.children.entrySet()) {
        List<String> subSuffix = getAll(prefix + child.getKey(), child.getValue());
        r.addAll(subSuffix);
    }
    return r;
}

public List<String> returnAllChildren(String str){
    List<String> r = new ArrayList<>();
    Node current = root;
    for (int i = 0; i < str.length(); i++) {
        char c = str.charAt(i);
        Node node = current.children.get(c);
        if (node == null) {
            // Not found
            return r;
        }
        current = node;
    }
    // If you don't need the prefix, you can just
    // return getAll("", current);
    return getAll(str, current);
}

public static void main(String[] args) {
    Trie trie = new Trie();
    trie.insert("abc");
    trie.insert("abcd");
    trie.insert("ab");

    List<String> r = trie.returnAllChildren("a");
    for (String s : r) {
        System.out.println(s);
    }
}
}