作業題:
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"));
}
}