【问题标题】:Collecting all words in a Trie in Java在 Java 中收集 Trie 中的所有单词
【发布时间】:2019-08-05 18:32:39
【问题描述】:

我正在尝试实现一种将 Trie 中的所有单词添加到列表的方法。我正在使用 Hashmap 来存储子节点的字符和引用节点。字符应仅包含字母 a-z。这是我的节点实现:

class Node {
    char c;
    HashMap<Character, Node> children = new HashMap<>();
    boolean isCompleteWord;

    public Node(char c){
        this.c = c;
        isCompleteWord = false;
    }
    public Node(){}
}

我不太确定从哪里开始,叶子节点将能够告诉我单词是否完整,所以我可以遍历 Trie 直到到达叶子节点并将字符附加到字符串也许吧,但是一旦添加了这个词,我如何遍历 trie 的不同分支来添加其他词?

【问题讨论】:

  • 什么是Trie
  • 嗯,我学到了新东西,谢谢:)
  • 一个问题。您只能存储 az 字符,即使您的 Trie 可能包含其他字符也不能存储其他字符?
  • Trie 只会从 a-z 存储字符,在插入方法中实现验证以确保这一点

标签: java data-structures trie


【解决方案1】:

首先要做的事情。您实际上不需要在节点类中存储字符属性,因为它已经隐式存储在其父节点的 children 属性中。
所以你的 Node 类实际上可以是:

class Node {
    HashMap<Character, Node> children = new HashMap<>();
    boolean isCompleteWord;

    public Node(){
        isCompleteWord = false;
    }
}

此外,与所有有根树一样,您的 Trie 将需要一个根。在将任何单词存储到 Trie 之前,您需要一个 root。

root = new Node();

根节点代表空字符串,所以如果你需要存储它,你必须检查rootisCompleteWord属性。

然后,要插入一个单词,比如 myWord,您需要从根开始,并应用以下规则:
- 考虑第一个字母 myWord[0],比如'c'。您需要区分两种情况,root是否包含键'c'。如果它不包含该单词,则需要在 Trie 中创建一个新节点。否则,您只需要继续沿着树枝“走”。
- 到达最后一个字母后,您只需将属性isCompleteWord 设置为true。这是addWord 的一个可能的(完全未经测试的)实现,它在 Trie 中添加一个单词,如果它已经存在则返回 true,否则返回 false

public bool addWord(Node node, String word, int idx){        
    if (idx == word.length() -1){ 
    // we're checking the last letter
        bool result = node.isCompleteWord;
        node.isCompleteWord = true;
        return result;
    } else {
        if (!node.children.containsKey(word.charAt(idx)){ 
        // no child with this letter, create one
            child = new Node()
            node.children.put(word.charAt(idx), child);
        } 
        return addWord(node.children(word.charAt(idx)), word, idx+1);
    }
}

要在 Trie 中添加一个单词,比如myWord,您只需按如下方式调用它:

addWord(root, myWord, 0);

一个检查单词是否存储在 trie 中的函数与添加单词的函数非常相似。

public bool containsWord(Node node, String word, int idx){        
    if (idx == word.length() -1){ 
        return node.isCompleteWord;
    } else {
        if (!node.children.containsKey(word.charAt(idx)){ 
        // no child with this letter, the word is not in the trie
            return false;
        } else {
            return containsWord(node.children(word.charAt(idx)), word, idx+1);
        }
    }
}

【讨论】:

    猜你喜欢
    • 2012-03-15
    • 1970-01-01
    • 2022-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-12
    • 2017-07-18
    • 2016-05-17
    相关资源
    最近更新 更多