(Data structure)Implement Trie && Add and Search Word

Implement Trie (Prefix Tree)

 Implement a trie with insertsearch, and startsWith methods.

Note:
You may assume that all inputs are consist of lowercase letters a-z

solution:

class TrieNode {
    // Initialize your data structure here.
    boolean isEnd;  //是否有单词以该字母结尾
    TrieNode[] sons;  //子节点[a-z]
    char value;        //保存该节点代表的字母值

    public TrieNode() {
        isEnd = false;
        sons = new TrieNode[26];  
    }
}

public class Trie {
    private TrieNode root;

    public Trie() {
        root = new TrieNode();
    }

    // Inserts a word into the trie.
    /**
     * 对于传入的单词,从左往右遍历每个字母,依次从根节点向下建树
     * 每个节点保存一个字母
     * @param word
     */
    public void insert(String word) {
        if (word == null || word.length() == 0)
            return;
        TrieNode p = root;   //工作指针,初始指向根节点
        for (int i = 0; i < word.length(); i++) {
            int pos = word.charAt(i) - 'a';  //hash-计算该字母对应的位置
            if (p.sons[pos] == null) {       //判断该位置是否为空
                p.sons[pos] = new TrieNode();
                p.sons[pos].value = word.charAt(i);
            }
            p = p.sons[pos];             //指向子节点
        }
        p.isEnd = true;  //标记该节点,表示有单词以之结尾
    }

    // Returns if the word is in the trie.
    /**
     * 类似建树过程,从左往右简历单词的每个字母,如果对应位置为空,则表示树中
     * 不存在该单词
     * @param word
     * @return
     */
    public boolean search(String word) {
        if (word == null || word.length() == 0)
            return false;
        TrieNode p = root;
        for (int i = 0; i < word.length(); i++) {
            int pos = word.charAt(i) - 'a';
            if (p.sons[pos] == null)
                return false;
            p = p.sons[pos];
        }
        return p.isEnd;  //false表示所查单词是树中某个单词的前缀,但不完全匹配
    }

    // Returns if there is any word in the trie
    // that starts with the given prefix.
    public boolean startsWith(String prefix) {
        if (prefix == null || prefix.length() == 0)
            return false;
        TrieNode p = root;
        for (int i = 0; i < prefix.length(); i++) {
            int pos = prefix.charAt(i) - 'a';
            if (p.sons[pos] == null)
                return false;
            p = p.sons[pos];
        }
        return true;
    }
}

// Your Trie object will be instantiated and called as such:
// Trie trie = new Trie();
// trie.insert("somestring");
// trie.search("key");

 


Add and Search Word

Design a data structure that supports the following two operations:

void addWord(word)
bool search(word)

search(word) can search a literal word or a regular expression string containing only letters a-z or .. A . means it can represent any one letter.

For example:

addWord("bad")
addWord("dad")
addWord("mad")
search("pad") -> false
search("bad") -> true
search(".ad") -> true
search("b..") -> true

Note:
You may assume that all words are consist of lowercase letters a-z.

solution:

public class WordDictionary {

    private Tode root;
    
    public WordDictionary() {
        root = new Tode();
    }
    
    // Adds a word into the data structure.
    /**
     * 与上题一致
     * @param word
     */
    public void addWord(String word) {
        if(word == null || word.length() == 0)
            return ;
        Tode p = root;
        for(int i=0; i<word.length(); i++){
            int pos = word.charAt(i) - 'a';
            if(p.sons[pos] == null){
                p.sons[pos] = new Tode();
                p.sons[pos].value = word.charAt(i);
            }
            p = p.sons[pos];
        }    
        p.isEnd = true;    
    }

    // Returns if the word is in the data structure. A word could
    // contain the dot character '.' to represent any one letter.
    /**
     * 因为.能匹配所有字母,导致不能直接hash判断字母是否存在,而必须对树进行深度优先遍历。
     * @param word
     * @return
     */
    public boolean search(String word) {
        if(word == null || word.length() == 0)
            return false;
        char[] arr = word.toCharArray();
        int index = 0;
        Tode p = root;
        return goSearch(arr, index, p);
    }

    private boolean goSearch(char[] arr, int index, Tode p) {
        if(index == arr.length)
            return p.isEnd;
        if(arr[index] == '.'){
            for(Tode n : p.sons){ //搜索当前节点的所有非空子节点
                if(n != null && goSearch(arr, index+1, n)) //若有节点搜索到匹配单词,则直接返回
                    return true;                        
            }
            return false;
        }else{
            int pos = arr[index] - 'a';
            if(p.sons[pos] != null)
                return goSearch(arr, index+1, p.sons[pos]);
            else
                return false;
        }
    }

    class Tode{
        boolean isEnd;
        Tode[] sons;
        char value;
        public Tode(){
            isEnd = false;
            sons = new Tode[26];
        }
    }
}

// Your WordDictionary object will be instantiated and called as such:
// WordDictionary wordDictionary = new WordDictionary();
// wordDictionary.addWord("word");
// wordDictionary.search("pattern");

 

你可能感兴趣的:(search)