4. 前缀树

前缀树 (prefix tree trie)

  1. 单个字符串中,字符从前到后的加到一棵多叉树上
  2. 字符放在路上,节点上有专属的数据项(常见的是pass和end值)
  3. 所有样本都这样添加,如果没有路就新建,如有路就复用
  4. 沿途节点的pass值增加1,每个字符串结束时来到的节点end值增加1
class Trie {
        TrieNode root;

        public Trie() {
            root = new TrieNode();
        }

        // 插入字符串
        public void insert(String str) {
            if (str == null) {
                return;
            }
            TrieNode curr = root;
            root.pass++;
            int path;
            char[] arr = str.toCharArray();
            for (char c : arr) {
                path = c - 'a';
                if (curr.nexts[path] == null) {
                    curr.nexts[path] = new TrieNode();
                }
                curr.nexts[path].pass++;
                curr = curr.nexts[path];
            }
            curr.end++;
        }

        // 搜索字符串
        public int search(String str) {
            if (str == null) {
                return -1;
            }
            char[] arr = str.toCharArray();
            int path;
            TrieNode curr = root;
            for (char c : arr) {
                path = c - 'a';
                if (curr.nexts[path] == null) {
                    return -1;
                }
                curr = curr.nexts[path];
            }
            return curr.end;
        }

        public void delete(String str) {
            // 删除节点
            if (search(str) == -1) {
                return;
            }
            char[] arr = str.toCharArray();
            int path;
            TrieNode curr = root;
            for (char c : arr) {
                path = c - 'a';
                if (--curr.nexts[path].pass == 0) {
                    curr.nexts[path] = null;
                    return;
                }
                curr = curr.nexts[path];
            }
            curr.end--;
        }
        public int startsWith(String str) {
            if (str == null) {
                return -1;
            }
            char[] arr = str.toCharArray();
            int path;
            TrieNode curr = root;
            for (char c : arr) {
                path = c - 'a';
                if (curr.nexts[path] == null) {
                    return -1;
                }
                curr = curr.nexts[path];
            }
            return curr.pass;
        }
    }

    class TrieNode {
        TrieNode[] nexts;
        int pass;
        int end;

        public TrieNode() {
            nexts = new TrieNode[26];
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于前缀树(Trie)来说,匹配包含某个字段的字符串可以通过以下步骤实现: 1. 从根节点开始,遍历字段中的每个字符。 2. 检查当前节点是否有一个子节点与当前字符匹配。如果有匹配的子节点,则移动到该子节点,并继续下一个字符的匹配。 3. 如果没有匹配的子节点,则表示没有与字段中的字符相匹配的路径,这时可以结束匹配过程。 4. 当遍历完字段中的所有字符时,检查当前节点是否为某个字符串的结尾。如果是,则表示该前缀树中存在匹配包含该字段的字符串。 下面是一个示例代码,演示如何使用前缀树匹配包含字段: ```python class TrieNode: def __init__(self): self.children = {} self.is_end_of_word = False class Trie: def __init__(self): self.root = TrieNode() def insert(self, word): node = self.root for char in word: if char not in node.children: node.children[char] = TrieNode() node = node.children[char] node.is_end_of_word = True def search(self, word): node = self.root for char in word: if char not in node.children: return False node = node.children[char] return node.is_end_of_word def starts_with(self, prefix): node = self.root for char in prefix: if char not in node.children: return False node = node.children[char] return True def contains_word(self, word): for i in range(len(word)): if self.starts_with(word[i:]): return True return False # 创建前缀树 trie = Trie() # 插入字符串 trie.insert("apple") trie.insert("banana") trie.insert("orange") # 检查是否包含字段 print(trie.contains_word("app")) # True print(trie.contains_word("nan")) # False print(trie.contains_word("rang")) # True ``` 在上述示例代码中,我们首先创建了一个前缀树对象 `trie`,并使用 `insert` 方法插入了三个字符串:"apple"、"banana" 和 "orange"。然后我们使用 `contains_word` 方法检查是否存在包含特定字段的字符串。在示例中,我们分别检查了 "app"、"nan" 和 "rang" 这三个字段,得到了相应的结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值