【蓝桥云课】字典树Trie
字典树: 单词的查找树,也就是26叉树,部分结构如下: 程序代码:
class TrieNode { char value;// 当前结点存储的字符 int num;// 有多少个单词经过了这个字符,从本字符到根就是这num个单词的前缀 boolean isword;// 是否构成一个完整的单词,true为是 TrieNode[] son;// 所有孩子存放在一个对象数组里,默认是26叉 public TrieNode() { num = 1;// 至少有一个字符经过本字符 isword = false;// 开始假定是false son = new TrieNode[26];// 本案例只考虑单词的26个字母 } } public class TrieTree { TrieNode root;// 字典树的根 public TrieTree() { root = new TrieNode();// 初始化根结点 } // 建树的过程就是不断地往字典树里插入单词 public void insertTrieTree(String s) { if (s == null || s.length() == 0) return;// 空串的处理 TrieNode node = root;// 先获取到根,因为插入的时候要一个一个字符处理,node会变的 char[] words = s.toCharArray();// 得到字符数组 for (int i = 0; i < words.length; i++) { int distance = words[i] - a;// 计算当前字符是当前根的第多少个孩子 if (node.son[distance] == null) { node.son[distance] = new TrieNode(); node.son[distance].value = words[i];// 存入当前字符 } else { node.son[distance].num++;// 经过当前字符的次数+1 } node = node.son[distance]; } node.isword = true;// 最后一个字符都存储完毕后,这个字符一定是单词的完整的结尾 } // 给定单词,查找其是否在字典树里 public boolean isContains(String s) { if (s == null || s.length() == 0) return false;// 空串的处理 TrieNode node = root;// 先获取到根,因为插入的时候要一个一个字符处理,node会变的 char[] words = s.toCharArray();// 得到字符数组 for (int i = 0; i < words.length; i++) { int distance = words[i] - a;// 计算当前字符是当前根的第多少个孩子 if (node.son[distance] != null) { node = node.son[distance];// 继续往下找 } else { return false; } } return node.isword; } // 给定前缀返回有多少个单词以它作为前缀 public int getPreFixNum(String prefix) { if (prefix == null || prefix.length() == 0) return 0;// 空串的处理 TrieNode node = root;// 先获取到根,因为插入的时候要一个一个字符处理,node会变的 char[] words = prefix.toCharArray();// 得到字符数组 for (int i = 0; i < words.length; i++) { int distance = words[i] - a;// 计算当前字符是当前根的第多少个孩子 if (node.son[distance] != null) { node = node.son[distance];// 继续往下找 } else { return 0; } } return node.num; } public static void main(String[] args) { TrieTree tree = new TrieTree(); String[] strs = { "banana", "band", "bee", "absolute", "acm", "acmer" }; String[] prefix = { "ba", "b", "band", "abc", "acm" }; for (String str : strs) { tree.insertTrieTree(str); } System.out.print("字典树中是否包含abc:"); System.out.println(tree.isContains("abc")); System.out.print("字典树中是否包含acm:"); System.out.println(tree.isContains("acm")); for (String str : prefix) { System.out.printf("%s的前缀为:%d ", str, tree.getPreFixNum(str)); } } }
运行结果:
字典树中是否包含abc:false 字典树中是否包含acm:true ba的前缀为:2 b的前缀为:3 band的前缀为:1 abc的前缀为:0 acm的前缀为:2