How to find the longest word in a trie?

蹲街弑〆低调 提交于 2019-12-10 13:57:01

问题


I'm having trouble understanding the concept of a trie. From the "trie" wikipedia entry I have this picture:

If I see this correctly, all leaf nodes in a trie will have the entire word spelled out and all parent nodes hold the characters leading up the the final leaf node. So, if I have a class called DigitalTreeNode defined by

public class DigitalTreeNode {
       public boolean isAWord;
       public String wordToHere; (compiles all the characters in a word together)
       public Map<String, DTN> children;
}

If I wanted to implement a method that returns the longest word in the trie would it simply involve finding the longest word at each leaf node? How would I implement a method such as:

public static String longestWord (DigitalTreeNode d);

I'm guessing it involves setting up a longest String variable, recursively going through each node and checking if it is a word, if it is a word and it's length is greater than the longest variable then longest = newWordLength . But, I'm not sure how the Map children fits in. How would I find the longest word in any trie using the method above?


回答1:


The leaf nodes do not contain the entire string usually (though they can), many time in a trie, a leaf node just contains a '$' sign to indicate this is the end of the string.

To find the longest word in a trie you can use a BFS on the tree, to first find the "last" leaf. The "last leaf" is the last element that was popped out of the BFS queue (after it was popped the algorithm of BFS stopped with an empty queue).
To get the actual word from this leaf you will need to go up from the leaf back to the root. This thread discussed how it can be done.

This solution is O(|S| * n), where |S| is the average length of a string, and n is the number of string in the DS.

If you can manipulate the trie DS, I assume it can be done better (but it seems not to be the issue in this question)

Pseudo code:

findLongest(trie):
  //first do a BFS and find the "last node"
  queue <- []
  queue.add(trie.root)
  last <- nil
  map <- empty map
  while (not queue.empty()):
     curr <- queue.pop()
     for each son of curr:
        queue.add(son)
        map.put(son,curr) //marking curr as the parent of son
     last <- curr
  //in here, last indicate the leaf of the longest word
  //Now, go up the trie and find the actual path/string
  curr <- last
  str = ""
  while (curr != nil):
      str = curr + str //we go from end to start   
      curr = map.get(curr)
  return str



回答2:


Another way of doing it is adding a boolean to signify if it's end of word AND the actual word like below:

 public class TrieNode {
        private HashMap<Character, TrieNode> children = new HashMap<>();
        private boolean endOfWord;
        private String actualWord;
        //setter getter
}

On insert, if it is end of word set boolean to true and the actual word

 public void insert(String insert) {
        HashMap<Character, TrieNode> parent = root.getChildren();
        TrieNode child = null;
        for (Character c : insert.toCharArray()) {
            child = parent.containsKey(c) ? parent.get(c) : new TrieNode();
            parent.put(c, child);
            parent = child.getChildren();

        }
        if (child != null) {
            child.setEndOfWord(true);
            child.setActualWord(insert);
        }
    }

Finally fetching it, you just do a BFS search, and once you have that node you have the actual word you are looking for.

  public TrieNode findLongest() {
        LinkedList<TrieNode> queue = new LinkedList();
        queue.push(root);
        TrieNode current = null;
        while (!queue.isEmpty()) {
            current = queue.pop();
            if (current.getChildren() != null) {
                for (TrieNode children : current.getChildren().values()) {
                    queue.push(children);
                }
            }
        }
        System.out.println(current.getActualWord()); // check here
        return current;
    }


来源:https://stackoverflow.com/questions/13191942/how-to-find-the-longest-word-in-a-trie

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!