前言
紧接着上一篇文章字符串匹配1,在上一篇文章里,我们主要总结归纳的是一个字符串和另一个字符串相比较。这篇文章,南国总结归纳的是两种常见的多模式匹配算法Trie树和AC自动机
多模式匹配:一个主串和多个模式串中间的匹配问题。
当然,聪明的你一定会问难道之前所学的单模式匹配的算法就不能用;爱解决问题吗? 答案是当然可以,但是用单模式的字符串算法解决这类问题总体的时间开销就会大很多,对于这类问题 我们更多的是采用一下的方法来进行解决。
话不多说,开始我们这篇文章的正文~
Trie树
Trie树,即字典树,它又被称之为单词查找树或者键树。是一种树形结构,也是一种哈希树的变种。
它的树结构模型如下图所示:
基本性质
- 根节点不包含字符,除根节点外的每一个子节点都包含一个字符
- 从根节点到某一节点。路径上经过的字符连接起来,就是该节点对应的字符串
- 每个节点的所有子节点包含的字符都不相同
应用场景
典型应用是用于统计,排序和保存大量的字符串(不仅限于字符串),经常被搜索引擎系统用于文本词频统计。
代码实现
Trie树结构的实现代码同时也是leetcode上的208题
代码实现总结起来就是:
- 1.创造节点类用来表示Trie树中每一个节点的信息
- 2.创建trie树,并实现简单的插入和查询功能
以下是全部代码:
/**
* leetcode 208 Implement Trie (Prefix Tree)
* @author xjh 2018.12.25
*/
class TrieNode {
public char value;
public boolean isWord; //这个boolean表示单词结束
public TrieNode[] children = new TrieNode[26]; //这里测试样例只需要输入a-z
public TrieNode() {
}
TrieNode(char c) {
TrieNode node = new TrieNode();
node.value = c;
}
}
class Trie {
TrieNode root;
/**
* Initialize your data structure here.
*/
public Trie() {
root = new TrieNode();
root.value = ' '; //Trie树的根节点不包含有效字符
}
/**
* Inserts a word into the trie.
*/
public void insert(String word) {
TrieNode t = root;
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i); //word的第i个字符
if (t.children[c - 'a'] == null) //如果孩子节点中没有该字符 则需要插入进去
t.children[c - 'a'] = new TrieNode(c);
t = t.children[c - 'a']; //树向下迭代
}
t.isWord = true;
}
/**
* Returns if the word is in the trie.
*/
public boolean search(String word) {
TrieNode t = root;
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i); //word的第i个字符
if (t.children[c - 'a'] ==