數學基礎:四、樹的應用1(利用樹結構存儲字典表)(待優化)

作業題:
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"));
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章