【蓝桥云课】字典树Trie

字典树: 单词的查找树,也就是26叉树,部分结构如下:
【蓝桥云课】字典树Trie_第1张图片
程序代码:

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\n", str, tree.getPreFixNum(str));
		}
	}
}

运行结果:

字典树中是否包含abc:false
字典树中是否包含acm:true
ba的前缀为:2
b的前缀为:3
band的前缀为:1
abc的前缀为:0
acm的前缀为:2

你可能感兴趣的:(蓝桥杯,算法,java,数据结构)