实现TrieTree中的易混淆的地方:注意查找字符串和字符串前缀的区别
1.查找字符串的话,要使用最后一个节点判断是否为单词,多种解决办法,可以设置标志位,tree:单词,false:不是单词,是字串的中间部分
或者也可以用第一种实现中的end值,end>0表示字符串结尾
2.查找前缀的话,没条件,只要trietree中有前缀单词即可
最后标注:数据结构的实现是多种多样的,掌握核心的灵魂才是关键
数组实现trieTree:缺点浪费空间,一般不使用
public class TrieTree {
//trietree主要应用于字符串查找
// trieTree node
class Node{
int pass;
int end;
Node[] next;
public Node(){
pass = 0;
end = 0;
next = new Node[26];
}
}
Node root;
// init trienode
public TrieTree(){
root = new Node();
}
// insert the string,this is create the trietree
public void insert(String word){
if (word == null)
return;
char[] chars = word.toCharArray();
Node node = root;
node.pass++;
for (int i = 0; i < chars.length; i++) {
int index = chars[i] - 'a';
if (node.next[index] == null){
node.next[index] = new Node();
}
node = node.next[index];
node.pass++;
}
node.end++;
}
// search the count of the word in the trietree
public int search(String word){
if (word == null)
return 0;
Node node = root;
char[] chars = word.toCharArray();
for (int i = 0; i < chars.length; i++) {
int index = chars[i] - 'a';
// don't exits the word
if (node.next[index] == null)
return 0;
node = node.next[index];
}
//判断查找前缀和查找字符串区别:查找单词得看结尾节点的end值,查找前缀不需要
return node.end;
}
// search the count of prefix of the word
public int prefixWord(String word){
if (word == null)
return 0;
char[] chars = word.toCharArray();
Node node = root;
for (int i = 0; i < chars.length; i++) {
int index = chars[i] - 'a';
if (node.next[index] == null)
return node.pass;
node = node.next[index];
}
return node.pass;
}
// delete the string of the word
// two condition:one just end,two has ends characters,这里仅仅删除一个字符串,想要删除多个,可以修改代码循环判断search(word)==0?,达到删除所有word的目的
public boolean delete(String word){
if (search(word) == 0)
return false;
Node node = root;
node.pass--;
char[] chars = word.toCharArray();
for (int i = 0; i < chars.length; i++) {
int index = chars[i] - 'a';
if (--node.next[index].pass == 0){
node.next[index] = null;
return false;
}
node = node.next[index];
}
node.end--;
return true;
}
}
字典实现trieTree:优点:灵活可以随机设置,节省空间,推荐使用
class Trie {
/**
* trietree主要应用于字符串查找
* 判断查找前缀和查找字符串区别:
* 查找单词得看结尾节点的end值,查找前缀不需要,
* 或者可以设一个标志位判断是字符还是前缀
*/
class TrieNode {
public boolean isWord;
public Map<Character, TrieNode> childrenMap = new HashMap<>();
}
private TrieNode root;
/** Initialize your data structure here. */
public Trie() {
root = new TrieNode();
}
/** Inserts a word into the trie. */
public void insert(String word) {
TrieNode cur = root;
for(int i = 0; i < word.length(); i++){
char c = word.charAt(i);
if(cur.childrenMap.get(c) == null){
// insert a new node if the path does not exist
cur.childrenMap.put(c, new TrieNode());
}
cur = cur.childrenMap.get(c);
}
cur.isWord = true;
}
/** Returns if the word is in the trie. */
public boolean search(String word) {
TrieNode cur = root;
for(int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if(cur.childrenMap.get(c) == null) {
return false;
}
cur = cur.childrenMap.get(c);
}
return cur.isWord;
}
/** Returns if there is any word in the trie that starts with the given prefix. */
public boolean startsWith(String prefix) {
TrieNode cur = root;
for(int i = 0;i < prefix.length(); i++){
char c = prefix.charAt(i);
if(cur.childrenMap.get(c) == null) {
return false;
}
cur = cur.childrenMap.get(c);
}
return true;
}
}