题目要求:
设计一种结构 ,该结构除了能够存储字符串之外,还要使得该结构能够满足下面的功能:
①:是否含有以某一个字符串为前缀的字符串
②:存储的字符串中,是否含有某个字符串
③:有多少个字符串以某一个字符串为前缀
实现代码:
package com.isea.ds;
public class TrieTree {
// 实现前缀树的时候,一定不要把字母放在了节点里,能让代码更加简洁。
public static class TrieNode {
public int path; // 有多少字符串到达过
public int end; // 有多少个字符串是以这个节点结尾的
public TrieNode[] nexts; // 路径,这个节点有多少个分支,也可以是下面的结构:
// public HashMap<Char,TrieNode> hashMap;
public TrieNode() {
path = 0;
end = 0;
nexts = new TrieNode[26]; // 规定节点有26条路径
// 如果判定一条路是否存在?查看子节点是否是为null,如果为null,该路不存在
}
}
public static class Trie {
private TrieNode root; // 前缀树上来一定要准备一个节点,就是头结点
public Trie() {
root = new TrieNode();
}
/**
* 向字典树中添加word字符串
*
* @param word 目标字符串
*/
public void insert(String word) {
if (word == null) {
return;
}
char[] chs = word.toCharArray();
TrieNode node = this.root;
int index = 0;
for (int i = 0; i < chs.length; i++) {
index = chs[i] - 'a';
if (node.nexts[index] == null) { // 如果走向该节点的路为null,就需要建立该节点
node.nexts[index] = new TrieNode();
}
node = node.nexts[index];
node.path++; // 每次添加完一个字符,标记多少字符到达过
}
node.end++; // 添加完一个字符串之后,维护多少字符串以该字符结尾。
}
// 查看word在出现过几次
public int search(String word) {
if (word == null) {
return 0;
}
char[] chs = word.toCharArray();
TrieNode node = this.root;
int index = 0;
for (int i = 0; i < chs.length; i++) {
index = chs[i] - 'a';
if (node.nexts[index] == null) {
return 0;
}
node = node.nexts[index];
}
return node.end;
}
// 查看有多少个字符串以pre为前缀
public int prefixNum(String pre) {
if (pre == null) {
return 0;
}
char[] chs = pre.toCharArray();
TrieNode cur = this.root;
int index = 0;
for (int i = 0; i < chs.length; i++) {
index = chs[i] - 'a';
if (cur.nexts[index] == null) {
return 0;
}
cur = cur.nexts[index];
}
return cur.path;
}
public void delete(String word) {
if (search(word) != 0) {
char[] chs = word.toCharArray();
TrieNode node = this.root;
int index = 0;
for (int i = 0; i < chs.length; i++) {
index = chs[i] - 'a';
if (--node.nexts[index].path == 0) { // 把到达节点path减 1
node.nexts[index] = null;
return;
}
node = node.nexts[index];
}
node.end--;
}
}
public static void main(String[] args) {
Trie trie = new Trie();
System.out.println(trie.search("isea")); // 0
trie.insert("isea");
System.out.println(trie.search("isea")); // 1
trie.delete("isea");
System.out.println(trie.search("isea")); // 0
trie.insert("isea");
trie.insert("isea");
trie.insert("isea");
System.out.println(trie.search("isea")); // 3
System.out.println(trie.prefixNum("isea")); // 3
}
}
}