代码之家  ›  专栏  ›  技术社区  ›  dc.

Trie实现

  •  13
  • dc.  · 技术社区  · 16 年前

    我正在尝试用Java实现一个非常简单的Trie,它支持3个操作。我希望它有一个insert方法、一个has方法(即trie中的某个单词)和一个toString方法以字符串形式返回trie。我相信我的插入工作正常,但has和toString被证明是困难的。这是我到目前为止所拥有的。

    
    public class CaseInsensitiveTrie implements SimpleTrie {
    
        //root node
        private TrieNode r;
    
        public CaseInsensitiveTrie() {
            r = new TrieNode();
        }
    
        public boolean has(String word) throws InvalidArgumentUosException {
            return r.has(word);
        }
    
        public void insert(String word) throws InvalidArgumentUosException {
            r.insert(word);
        }
    
        public String toString() {
            return r.toString();
        }
    
        public static void main(String[] args) {
    
            CaseInsensitiveTrie t = new CaseInsensitiveTrie();
    
            System.out.println("Testing some strings");
            t.insert("TEST");
            t.insert("TATTER");
            System.out.println(t.has("TEST"));
        }
    }
    

    
    public class TrieNode {
    
        //make child nodes
        private TrieNode[] c;
        //flag for end of word
        private boolean flag = false;
    
        public TrieNode() {
            c = new TrieNode[26]; //1 for each letter in alphabet
        }
    
        protected void insert(String word) {
            int val = word.charAt(0) - 64;
    
            //if the value of the child node at val is null, make a new node
                    //there to represent the letter
            if (c[val] == null) {
                c[val] = new TrieNode();
            }
    
            //if word length > 1, then word is not finished being added.
            //otherwise, set the flag to true so we know a word ends there.
            if (word.length() > 1) {
                c[val].insert(word.substring(1));
            } else {
                c[val].flag = true;
            }
        }
    
        public boolean has(String word) {
            int val = word.charAt(0) - 64;
            if (c[val]!=null && word.length()>1) {
                c[val].has(word.substring(1));
            } else if (c[val].flag==true && word.length()==1) {
                return true;
            }
    
            return false;
        }
    
        public String toString() { 
            return "";
        }
    }
    

    因此,基本上,当创建一个Trie时,一个三元组被创建为具有26个子级的根。当尝试插入时,将在该根节点上调用insert,从而在正确的位置递归创建一个新节点,并继续执行,直到单词完成。我相信这个方法是正确的。

    因为我的功能坏了,我很 有 出于某种原因,把返回语句放在括号之外。我不能将它包含在else子句中,否则编译器会抱怨。除此之外,我认为该方法应该进行一些调整,但我无法为我的生活找出它。

    toString是我试图对付的野兽,但我扔给它的东西都不管用,所以在我解决问题之前,我会一直保持这种状态。如果我开始工作,我可能会想出一种方法,将其重新格式化为toString函数。

    int val=word.charAt(0)-64的用途;这是因为输入的每个字符串都必须是大写的(我将创建一个字符串格式化函数,以确保以后可以这样做),所以第一个字母的int值-64将是它在数组中的位置。ie数组索引0是A,所以A=64,A-64=0。B=65,B-64=1,依此类推。

    6 回复  |  直到 7 年前
        1
  •  12
  •   Anon.    16 年前

    你的 has

    if (c[val]!=null && word.length()>1) {
        return c[val].has(word.substring(1)); //<-- Change is on this line
    } else if (c[val].flag==true && word.length()==1) {
        ...etc
    

    您执行递归调用,但确实需要让该值传播回原始调用方。

        2
  •  7
  •   Gaurav Kohli    14 年前

    也许您可以使用“Map c”而不是“Triode[]c”,这将允许您对所有类型的字符(大写/小写,甚至特殊字符)使用它,甚至可以节省空间(在每个字符级别分配26个字符数组)

        3
  •  1
  •   Peter O. Manuel Pinto    11 年前

    public class Tries {
    
    class Node {
        HashMap<Character, Node> children;
        boolean end;
        public Node(boolean b){
            children = new HashMap<Character, Tries.Node>();
            end = false;
        }
    }
    private Node root;
    public Tries(){
        root = new Node(false);
    }
    public static void main(String args[]){
        Tries tr = new Tries();
        tr.add("dog");
        tr.add("doggy");
    
        System.out.println(tr.search("dogg"));
        System.out.println(tr.search("doggy"));
    }
    private boolean search(String word) {
        Node crawl = root;
        int n = word.length();
        for(int i=0;i<n;i++){
            char ch = word.charAt(i);
            if(crawl.children.get(ch) == null){
                return false;
            }
            else {
                crawl = crawl.children.get(ch);
                if(i==n-1 && crawl.end == true){
                    return true;
                }
    
            }
        }
        return false;
    }
    private void add(String word) {
        Node crawl = root;
        int n = word.length();
        for(int i=0;i<n;i++){
            char ch = word.charAt(i);
            if(crawl.children.containsKey(ch)){
                crawl = crawl.children.get(ch);
            }
            else {
                crawl.children.put(ch, new Node(false));
                Node temp = crawl.children.get(ch);
                if(i == n-1){
                    temp.end = true;
                }
                crawl = temp;
                System.out.println(ch + "      " + crawl.end);
    
            }
        }
    }
    
    }
    
        4
  •  1
  •   Dheeraj Sachan    10 年前

    import java.util.ArrayList;
    import java.util.List;
    
    class Trie {
    
        private static Node root = new Node(' ', false);
    
        static int getIndex(char x) {
            return ((int) x) - ((int) 'a');
        }
    
        static class Node {
            char data;
            boolean isLeaf;
            Node[] children;
    
            Node(char data, boolean leaf) {
                this.data = data;
                this.isLeaf = leaf;
                this.children = new Node[26];
            }
    
        }
    
        static void insert(String data, Node root) {
            if (data == null || data.length() == 0) {
                return;
            }
            Node child = root.children[getIndex(data.charAt(0))];
            if (child == null) {
                Node node = new Node(data.charAt(0), data.length() == 1);
                root.children[getIndex(data.charAt(0))] = node;
                if (data.length() > 1) {
                    insert(data.substring(1, data.length()), node);
                }
            } else {
                if (data.length() == 1) {
                    child.isLeaf = true;
                } else {
                    insert(data.substring(1, data.length()), child);
                }
            }
        }
    
        static boolean find(String data, Node root) {
            if (data == null || data.length() == 0) {
                return true;
            }
            char x = data.charAt(0);
            //note that first node ie root is just dummy, it just holds important
            Node node = root.children[getIndex(x)];
            if (node == null) {
                return false;
            } else {
                if (data.length() == 1) {
                    return node.isLeaf;
                } else {
                    return find(data.substring(1, data.length()), node);
                }
            }
        }
    
        static boolean delete(String data, Node root) {
            if (data == null || data.length() == 0) {
                return false;
            }
            char x = data.charAt(0);
            //note that first node ie root is just dummy, it just holds important
            Node node = root.children[getIndex(x)];
            if (node == null) {
                return false;
            } else {
                if (data.length() == 1) {
                    node.isLeaf = false;
                    boolean allNull = true;
                    for (Node node1 : node.children) {
                        allNull = allNull && node1 == null;
                    }
                    return allNull;
                } else {
                    boolean delete = delete(data.substring(1, data.length()), node);
                    if (delete) {
                        node.children[getIndex(x)] = null;
                        if(node.isLeaf){
                            return false;
                        }
                        boolean allNull = true;
                        for (Node node1 : node.children) {
                            allNull = allNull && node1 == null;
                        }
                        return allNull;                }
                }
            }
            return false;
        }
    
    
        private static List<String> strings = new ArrayList<>();
    
        private static List<String> getAll() {
            strings = new ArrayList<String>();
            findAllDFS(root, "");
            return strings;
        }
    
        private static void findAllDFS(Node node, String old) {
            if (node != null) {
                if (node.data != ' ') {
                    old = old + node.data;
                }
                if (node.isLeaf) {
                    strings.add(old);
                }
                for (Node node1 : node.children) {
                    findAllDFS(node1, old);
                }
            }
        }
    
        public static void main(String[] args) {
            insert("abc", root);
            insert("xyz", root);
            insert("abcd", root);
            insert("abcde", root);
    
    
            delete("abcd", root);
    
     /*       System.out.println(find("abc", root));
            System.out.println(find("abcd", root));
            System.out.println(find("ab", root));
            System.out.println(find("xyz", root));*/
    
    
            System.out.println(getAll());
        }
    
    
    }
    
        5
  •  1
  •   Enrico Giurin    9 年前

    以下是我的实施:

    public class Tries {
    private static class Leaf {
        private Leaf(char c) {
            this.c=c;
        }
        char c;
        int counter = 1;
        List<Leaf> leaves = new ArrayList<>(10);
    }
    private Leaf root = new Leaf('0');
    public void add(String word) {
        Leaf current = root;
        Leaf newLeaf = null;
        for (char c : word.toCharArray()) {
            boolean found = false;
            for (Leaf leaf : current.leaves) {
                if (leaf.c == c) {
                    current = leaf;
                    current.counter++;
                    found=true;
                    break;
                }
            }
            if (!found) {
                newLeaf = new Leaf(c);
                current.leaves.add(newLeaf);
                current = newLeaf;
            }
        }
    }
    public int find(String partial) {
        Leaf current = root;
        for (char c : partial.toCharArray()) {
            boolean found = false;
            for (Leaf leaf : current.leaves) {
                if (leaf.c == c) {
                    current=leaf;
                    found=true;
                    break;
                }
            }
            if(!found) return 0;
        }
        return current.counter;
    }
    
    public boolean hasWord(String partial) {
        return find(partial)>0;
        }
    }
    
    推荐文章