它所在的地方:
public Iterator<String> iterator() {
return new TrieIterator();
}
调用它来实现我自己的迭代器。我已经尝试在数组+ 1中使用一个位置来表示hasNext(),同时将事物与大小,数字或节点以及子项进行比较,并且做得很短。我最近的尝试是(下面)的,但是没有用。
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;
}
请不要改变特里的当前实施情况:)
答案 0 :(得分:0)
您使用hasNext()
实施this.children.hasChildren();
的尝试不会奏效,因为children
是TrieNode
的数组,所以它没有任何hasChildren()
{1}}方法。
hasChildren()
方法是TrieNode
的方法,而不是children
数组。
您需要跟踪当前节点,当前节点中的位置以及到目前为止看到的所有字符。如果有更多的单词,hasNext()
应该返回true,这意味着如果节点是一个完整的单词,或者它是否有任何尚未访问过的完整单词的子节点。 (但是,我假设叶子节点总是满字,所以后一个测试可能只是节点有任何尚未访问过的子节点。)
您需要决定是否会在较长的单词之前返回较短的单词(一旦到达完整的单词节点,或者仅在访问其子单元后,您是从next()
返回单词吗?)您将还需要维护一堆节点,以便在您下降到子节点后,可以返回到父节点中的先前位置。
这不是一项微不足道的任务。我建议从一个非常小的单词构建的Trie开始(例如&#34; a&#34;,&#34;&#34;和&#34; at&#34;)并完全获得在你移到三个字母或更多单词之前调试。
(如果你在迭代过程中修改了Trie,你也应该考虑你打算做什么。标准java.util
类会在每次修改时更新一个计数器,并测试它没有&#39 ;在迭代器中进行了更改。如果有,则抛出ConcurrentModificationException
。使用此策略的迭代器称为 fail-fast iterators 。)