字典樹
字典樹是一種樹形結構,優點是利用字符串的公共前綴來節約存儲空間。在這提供一個自己寫的Java實現,非常簡潔。
- 根節點沒有字符路徑。除根節點外,每一個節點都被一個字符路徑找到。
- 從根節點到某一節點,將路徑上經過的字符連接起來,為對應字符串。
- 每個節點向下所有的字符路徑上的字符都不同
每個結點維持兩個變量的記錄:path表示字符路過這個結點的次數(即表示存在以當前結點為前綴的字符有多少個);end記錄以當前結點為結束的字符有多少個。
public class Main {
public static void main(String[] args) {
Trie trie = new Trie();
trie.add("a");
trie.add("ab");
trie.add("ac");
trie.add("abc");
trie.add("acb");
trie.add("abcc");
trie.add("aab");
trie.add("abx");
trie.add("abc");
System.out.println(trie.get("abc"));
System.out.println(trie.getPre("ab"));
}
}
/**
* path表示字符路過這個結點的次數(即表示存在以當前結點為前綴的字符有多少個);
* end記錄以當前結點為結束的字符有多少個。
*/
class TrieNode {
public int path;
public int end;
public TrieNode[] nexts;
public TrieNode() {
path = 0;
end = 0;
//只能存英文小寫字母,如果是ASCII碼可以生成256大小的數組
//如果想存更多種類的字符可以改為map結構
nexts = new TrieNode[26];
}
}
class Trie {
private TrieNode root;
Trie() {
root = new TrieNode();
}
/**
* 字典樹的加入過程
*/
public void add(String word) {
if (word == null) return;
char[] chars = word.toCharArray();
TrieNode node = root;
int index = 0;
for (char c : chars) {
index = c - 'a';
if (node.nexts[index] == null) {
node.nexts[index] = new TrieNode();
}
node = node.nexts[index];
node.path++;
}
node.end++;
}
/**
* 字典樹查詢目標單詞出現的次數
*/
public int get(String word) {
if (word == null) return 0;
char[] chars = word.toCharArray();
TrieNode node = root;
int index = 0;
for (char c : chars) {
index = c - 'a';
if (node.nexts[index] == null) return 0;
node = node.nexts[index];
}
return node.end;
}
/**
* 字典樹查詢以目標前綴的單詞有多少個
*/
public int getPre(String word) {
if(word ==null) return 0;
char[] chars = word.toCharArray();
TrieNode node = root;
int index = 0;
for (char c : chars) {
index = c - 'a';
if(node.nexts[index]==null)
return 0;
node = node.nexts[index];
}
return node.path;
}
}