Java - 删除trie中的单词(请伪代码)

时间:2014-04-22 17:46:04

标签: java trie

我一直在努力尝试计划如何从特里删除单词。我有一个实现,它在节点上使用一维数组,它保存一个单词的下一个字符。我理解如何摆脱整个单词,但不能解释包含较小单词的较大单词,以便删除下面的trie中的“bat”,“battle”,“as”和“any”(*)表示单词的结尾)并留下“电池”,“战场”,“问”和“任何人”:

    root 
    / \
   a   b-a-t*-t-e-r-y*
  / \         |
 n   s*-k*    l-e*-f-i-e-l-d*
 |
 y*-w-h-o*

以下是我迄今为止实施的特里:

public class TrieNode {

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

    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 fullWord;
    }
}

public class Trie implements Iterable<String> {

    private int numOfNodes;
    private int numOfWords;
    private TrieNode root = new TrieNode(' ', null);

    public Trie() {
    }

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

        int index = 0;
        TrieNode iterator = root;

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

            iterator = iterator.children[s.charAt(index) - 97];

            index++;

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

    // Issues on this one 
    public void deleteWord(String s) {
        if(s.length() == 0) return; 
        // make method to check for empty trie
        else if(!(hasWord(s))) return;
        else {
            TrieNode iterator = root;
            int index = 0;

            while(index < s.length()){
                if(iterator.children[index] != null){
                    /* What would (in pseudo code) need to be put here to account for this */
                }
            }
        }
    }

    public boolean hasWord(String s) {
        TrieNode current = root;

        while(current != null){
            for (int i = 0; i < s.length(); i++) {
                if(current.letter == ' ') return false; // error here probably
                else current = current.children[i];
            }
            if (current.fullWord == true) return true;
            else return false;
        }
        return false;
    }

    public Iterator<String> iterator() {
        return new TrieIterator();  // has basic iterator functions
    }
}

任何想法?

1 个答案:

答案 0 :(得分:1)

public class TrieNode {

// a letter=='*' means end of word
// a letter=='\0x' means root node
protected char letter = ' ';
protected TrieNode[] children = new TrieNode[26];

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

public boolean hasChildren(){
    int index = 0;

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

// don't understand the purpose of this 
public TrieNode nodeForLetter(char ch) {
    return children[ch - 97];
}

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

public void deleteWord( String wordToBeDeleted )
{
     // append an asterisk will delete the end of 
     // the word without any special programming
     realDeleteWord( wordToBeDeleted + "*" ); 
}  // deleteWord

// this function will return true if this 
// object has to be deleted 
private boolean realDeleteWord( String wordToBeDeleted )
{
    if( wordToBeDeleted.isEmpty() ) 
        return; // simplest case 
    else
    {
       // split the word in the first character and the rest of 
       // string 
       char firstChar = wordToBeDeleted.charAt(0);
       String restOfWord = substr( wordToBeDeleted, 1, rest_of_string );

       // first you have to treat the rest of the word
       realDeleteWord( restOfWord )

       // next you have to treat the first char 
       // if I don't have any children, I have to delete myself
       if( ! hasChildren() && firstChar == letter ) 
       {
           // PENDING: THIS VERY OBJECT HAS TO BE DELETED, 
           // HOW TO IMPLEMENT THIS? RETURN TRUE TO INFORM THE PARENT?
           return true; 
       }
       else
       {
          // DO NOTHING: either there are children or 
          // this character is not the same as the one 
          // given as parameter
       } // hasChildren()...
    } 
} // realDeleteWord

}
嗯......编程课的典型练习,是这样的吗?记住,递归是神圣的,迭代是人类。