【问题标题】:java - overriding iterator?java - 覆盖迭代器?
【发布时间】:2014-06-08 23:46:57
【问题描述】:

老实说,我花了几天时间研究这个问题并试图弄清楚,但结果很短。目标是查看一个 trie 节点是否有下一个,如果有,它是什么。

它的调用位置:

public Iterator<String> iterator() {
    return new TrieIterator();
}

调用它来实现我自己的迭代器。我已经尝试在 hasNext() 中使用数组 + 1 中的位置,还将事物与大小、数量或节点以及子节点进行比较,但结果不足。我最近的尝试类似于(如下),但不起作用。

hasNext() {
return this.children.hasChildren(); /* doesn't work */
} 

public class TrieIterator implements Iterator<String> {

    public TrieIterator(){
    }

    public boolean hasNext() {
        return false;
    }

    public String next() {

        return null;
    }

    public void remove() {
         throw new UnsupportedOperationException();
    }
}

这也是 trieNode 类:

public class TrieNode {

    protected char letter = ' ';
    protected TrieNode parentNode = null;
    protected boolean fullWord = false;
    protected TrieNode[] children = new TrieNode[26];
    protected int prefixes = 0;

    public TrieNode(char letter, TrieNode parentNode){
        this.letter = letter;
        this.parentNode = parentNode;
    }

    public boolean hasChildren(){
        int index = 0;

        while(index < children.length){
            if(children[index] != null) {
                return true;
            }
            index++;
        }
        return false;
    }

    public TrieNode nodeForLetter(char ch) {
        return children[ch - 97];
    }

    public boolean isEndOfWord() {
        return letter == '*';
    }
}

增删如下:

public void addWord(String s) {
    if (hasWord(s)) return;

    int index = 0;
    TrieNode current = root;
    char[] letters = s.toCharArray();

    while(index < s.length()){
        TrieNode child = current.children[letters[index] - 97];
        if(child == null){
            child = new TrieNode(letters[index], current);
            child.prefixes++;
            numOfNodes++;
        }

        current = child;
        index++;

        if(index == s.length()){
            current.fullWord = true;
            numOfWords++;
        }
    }
}

public void deleteWord(String s) {
    if(s.length() == 0) return;
    if(size() == 0) return;
    if(!hasWord(s)) return;

    TrieNode current = root;
    for (char ch : s.toCharArray()) {
        TrieNode child = current.children[s.charAt(ch) - 97];
        if(child.prefixes == 1){
            child = null;
            return;
        }
        else{
            child.prefixes--;
            current = child;
        }
    }
    current.fullWord = false;
}

public boolean hasWord(String s) {
    if(size() == 0) return false;

    char[] letters = s.toCharArray();
    int l = letters.length;
    TrieNode current = root;

    int i;
    for (i = 0; i < l; i++){
        if (current == null) return false;
        current = current.children[letters[i] - 97];
    }

    if (i == l && current == null) return false;
    if (current != null && !current.fullWord) return false;

    return true;
}

请不要更改 trie 的当前实现 :)

【问题讨论】:

  • 什么“不起作用”,您如何获得迭代器的实例?
  • 首先,定义如何遍历 trie 的所有元素来完成一项基本任务,例如打印它们。然后,实现TrieIterator中的方法来实现这个行为。
  • 抱歉,您的问题具体是什么?你是在找人给你写TrieIterator吗?
  • @ruakh 不,我想解释一下如何通过 trie,然后我可以自己实现迭代器。
  • @LuiggiMendoza 这就是我目前遇到的问题。

标签: java iterator iteration trie


【解决方案1】:

您尝试用this.children.hasChildren(); 实现hasNext() 将不起作用,因为childrenTrieNode 的数组,因此它没有任何hasChildren() 方法。

hasChildren() 方法是 TrieNode 的方法,而不是它的 children 数组。

您需要跟踪当前节点、当前节点中的位置以及到目前为止看到的所有字符。 hasNext() 如果还有更多单词,则应该返回 true,这意味着该节点是否是一个完整的单词,或者它是否有任何尚未访问的子节点是完整的单词。 (但是,我假设叶子节点总是完整的单词,所以后面的测试可以简单地是节点是否有任何尚未访问的子节点。)

您需要决定是否在较长的单词之前返回较短的单词(您是在到达完整单词节点后立即返回来自next() 的单词,还是仅在访问其子节点后返回?)您还需要维护一个节点栈,这样当你下降到一个子节点后,你可以回到你之前在父节点中的位置。

这不是一项简单的任务。我建议从由一组非常小的单词(如“a”、“an”和“at”)构建的 Trie 开始,并在继续使用三个或更多字母的单词之前对其进行全面调试。

(您还应该考虑如果在迭代时修改了 Trie,您打算做什么。标准的 java.util 类会在每次修改时更新一个计数器,并测试它在迭代器中没有改变. 如果有,他们会抛出 ConcurrentModificationException。使用这种策略的迭代器被称为 fail-fast 迭代器。)

【讨论】:

  • 测试驱动开发有很大帮助,尤其是当算法不“适合人们的想法”时,因为很容易检查一切是否仍然有效
  • 你能告诉我如何访问当前节点吗?然后我想我从那里得到它!谢谢!
  • 你有什么建议吗,2小时后我还是迷路了?
  • 迭代器将有一个当前节点的实例变量,在创建迭代器时最初将设置为根节点,然后在迭代 trie 时会发生变化。
猜你喜欢
  • 1970-01-01
  • 2023-03-23
  • 2020-07-08
  • 2019-04-26
  • 2016-09-18
  • 1970-01-01
  • 2014-09-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多