tire 学习心得
Posted kaly
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了tire 学习心得相关的知识,希望对你有一定的参考价值。
一、碎语&心得
下一周我准备学习 AC 自动机(这个名字是真的喜感不知道为什么要叫做 AC 自动机)。所以我要先学他的前置条件字典树,因为已经有了用数组模拟树的经验,再加上树也学了不少了而且字典树很简单。所以我的学习没有遇到什么困难,花了半个小时看了一会儿模板,在搞懂了几个关键点之后我就写出来了,代码量也比较小,在一些特定问题中对程序运行速度的优化也非常优秀,据我所知这个数据结构经常被用于搜索引擎,这个数据结构具有简单好用,代码量小,这两个优点,像树状数组一样。。而且查找只和字符串长度相关,与 n 无关,在数据量大且单词长度不长的情况下,肯定会比平衡查找树还优秀。
虽然是我的心得但原理还是稍微记一下,到时候方便复习,而且万一有大佬浏览蒟蒻的心得呢,图就不配了(其实就是太麻烦了懒得整)。
二、实现原理
字典树其实是一颗根节点不存放数据的树,每个节点至多有 26 个孩子(用于字符串只包含 26 个字母的情况,当然大部分时候都是运用这种情况)他的原理就好像查字典一样,你要查 apple,肯定首先翻到 a 那一块去,然后在翻到第二个字母是 p 的那一页去等等等等。表现在代码里就是查找根节点有没有挂着 a 这个节点,再看 a 下面有没有挂着 p 这个节点。插入也同理,一个字母一个字母的来新建节点,如果已经建立了,那就直接跳过就行了,在查找时还要注意一件事,那就是标记挂着最后一个字母的节点为结束节点(其实字母挂在边上),不然插入 apple 之后查找 ap 也会返回真。
三、代码
头文件和主函数根本不重要就贴个类吧。
c++代码:
template<int T> class trie { private: int tree[T][30],cnt; bitset<T>mark; public: void insert(string a) { int r = 0; for(int i=0;i<a.size();i++) { int x = a[i]-‘a‘; if(tree[r][x] == 0) { tree[r][x] = ++cnt; } r = tree[r][x]; } mark[r] = 1; } bool find(string a) { int r = 0; for(int i=0;i<a.size();i++) { int x = a[i]-‘a‘; if(tree[r][x] == 0) { return false; } r = tree[r][x]; } return mark[r]; } trie() { cnt = 0; } };
因为我还在学习 java,所以我同时也用 java 写了一遍。
java代码:
public class trie { private int[][] tree; private int cnt; private boolean[] mark; public trie(int size) { tree = new int[200010][size]; mark = new boolean[200010]; cnt = 0; } public void insert(String s) { int r = 0; for(int i = 0;i < s.length();i++) { int x = s.charAt(i) - ‘a‘; if(tree[r][x] == 0) { tree[r][x] = ++cnt; } r = tree[r][x]; } mark[r] = true; } public boolean find(String s) { int r = 0; for(int i = 0;i < s.length();i++) { int x = s.charAt(i) - ‘a‘; if(tree[r][x] == 0) { return false; } r = tree[r][x]; } return mark[r]; } }
同时还顺带学习了一下 java 的字符串和二维数组,java 没有重载运算符不能像数组一样用字符串类真的不方便,但是却能很好的区分数组和类,也算是有利有弊吧。
有了这个下周我就可以学 AC 自动机了,想想还是挺兴奋的。
以上是关于tire 学习心得的主要内容,如果未能解决你的问题,请参考以下文章
POJ - 2778 ~ HDU - 2243 AC自动机+矩阵快速幂