作业题:
https://time.geekbang.org/column/article/76481
利用树结构存储字典表,这里没有学习下一节(下一节的实现肯定更加高效)
这里只是用最简单的方法来实现(时间和空间复杂度都没有考虑)
代码如下:
public class Lesson11_1 {
// 正则,只允许输入字母
String regex = "^[A-Za-z]+$";
// 构建字典对象
class TreeNode {
private char root; // 根节点,最根节点构建时为0
private boolean end; // 为end说明从根节点到此节点已结束,能遍历到说明能匹配
private TreeNode[] leaves; // 子节点,存储非首字母
public TreeNode(char c) {
this.root = c;
this.end = false; // 默认没有结束,后面手动给结束
this.leaves = new TreeNode[26]; // 给分配26个空间
}
// 私有方法(不用管),内部调用,往里面追加字母
private TreeNode append(char c) {
TreeNode[] leaves = this.leaves;
TreeNode leaf = leaves[c - 'a']; // 为相应下标0-25赋值
if (leaf == null) { // 之前此节点下没有创建元素,需手动创建
leaf = new TreeNode(c);
leaves[c - 'a'] = leaf;
}// 如果有该节点,直接返回即可,无需重复创建(否则可能覆盖掉之前该节点下的元素)
return leaf;
}
// 存入单词
public TreeNode build(String keyword) {
if (keyword == null || keyword == "") {
return this;
}
// 必须正确单词
Assert.assertTrue(keyword.matches(regex));
// 默认字典表数据都为小写字母
keyword = keyword.toLowerCase();
int length = keyword.length();
TreeNode tmp = this;
TreeNode root = this; // 为了再最后返回,临时存储
for (int i = 0; i < length; i++) {
char c = keyword.charAt(i);
tmp = tmp.append(c); // 循环创建子节点,tmp临时存储循环的节点元素
}
tmp.end = true; // 在最后节点中,手动加结束标志,便于查找到中间返回
return root;
}
// 查找单词
public boolean search(String keyword) {
if (keyword == null || keyword == "") {
return false;
}
// 必须正确单词
Assert.assertTrue(keyword.matches(regex));
// 默认字典表数据都为小写字母
keyword = keyword.toLowerCase();
TreeNode tmp = this;
int length = keyword.length();
for (int i = 0; i < length; i++) {
char c = keyword.charAt(i);
TreeNode[] leaves = tmp.leaves;
tmp = leaves[c - 'a']; // 为相应下标0-25赋值
if (tmp == null) { // 之前此节点下没有创建元素,没有找到
return false;
}
}
// 如果end == true,说明之前构建到这时就结束了。反之要查找的单词不是完整的单词
return tmp.end;
}
}
@Test
public void test() {
// 这是要构建的字典表
String[] keywords = {"hello", "world", "helloworld"};
// 循环初始化完成字典表的构建
TreeNode treeNode = new TreeNode((char) 0);
for (String keyworld : keywords) {
treeNode.build(keyworld);
}
System.out.println("构建成功,后续开始进行查找");
Assert.assertTrue(treeNode.search("hello"));
Assert.assertTrue(treeNode.search("world"));
Assert.assertTrue(treeNode.search("helloworld"));
Assert.assertFalse(treeNode.search("hell"));
Assert.assertFalse(treeNode.search("helo"));
Assert.assertFalse(treeNode.search("worlda"));
}
}