trie -- suffix tree -- suffix automa 有这么几个情况:

用户输入即时响应AJAX搜索框, 显示候选名单。

搜索引擎keyword统计数量。

后缀树(Suffix Tree): 从根到叶子表示一个后缀。



只从这一个简单的描写叙述,我们能够概念上解决以下的几个问题:



P:查找字符串o是否在字符串S中

A:若o在S中,则o必定是S的某个后缀的前缀。 用S构造后缀树。按在trie中搜索字串的方法搜索o就可以。

P: 指定字符串T在字符串S中的反复次数。

A: 假设T在S中反复了两次,则S应有两个后缀以T为前缀,搜索T节点下的叶节点数目即为反复次数。



P: 字符串S中的最长反复子串。

A: 同上。找到最深的非叶节点T。



P: 两个字符串S1。S2的最长公共子串。

A: 广义后缀树(Generalized Suffix Tree)存储_多个_字符串各自的全部后缀。把两个字符串S1#。S2$增加到广义后缀树中,然后同上。

(A longest substring common to s1 and s2 will be the path-label of an internal node with the

greatest string depth in the suffix tree which has leaves labelled with suffixes from both the

strings.)



Suffix Automa: 识别文本全部子串的辅助索引结构。

以下的代码是直接翻译[1]中算法A:

/*Directed Acyclic Word Graph

*/
#include <stdlib.h>
#include <string.h> typedef struct State{
struct State *first[26], *second[26];
struct State *suffix;
}State; State *sink, *source; State *new_state(void)
{
State *s = malloc(sizeof *s);
if(s){
memset(s, 0, sizeof *s);
}
return s;
} /*state:
parent -- [x] with xa = tail(wa)
child -- [tail(wa)]
new child -- [tail(wa)]_{wa}
*/
State *split(State *parent, int a)
{
int i;
/*current state, child, new child*/
State *cs = parent, *c = parent->second[a], *nc = new_state(); //S1
parent->first[a] = parent->second[a] = nc; //S2
for(i = 0; i < 26; ++i){
nc->second[i] = c->second[i]; //S3
}
nc->suffix = c->suffix; //S4
c->suffix = nc; //S5 for(cs = parent; cs != source; ){//S6,7
cs = cs->suffix; //S7.a
for(i = 0; i < 26; ++i){
if(cs->second[i] == c)cs->second[i] = nc; //S7.b
else goto _out; //S7.c
}
}
_out:
return nc; //S8
} /*state:
new sink -- [wa]
*/
void update(int a)
{
/*suffix state, current state, new sink*/
State *ss = NULL, *cs = sink, *ns = new_state(); //U1,2
sink->first[a] = ns; while(cs != source && ss == NULL){//U3
cs = cs->suffix; //U3.a
if(!cs->first[a] && !cs->second[a]){
cs->second[a] = ns; //U3.b.1
}else if(cs->first[a]){
ss = cs->first[a]; //U3.b.2
}else if(cs->second[a]){
ss = split(cs, a); //U3.b.3
}
} if(ss == NULL){ss = source;} //U4
ns->suffix = ss; sink = ns; //U5
} int build_dawg(char *w)
{
sink = source = new_state();
for(; *w; ++w){update(*w-'a');}
}

我还在努力理解中,没有測试。

[1] the smallest automation recognizing the subwords of a text

https://cbse.soe.ucsc.edu/sites/default/files/smallest_automaton1985.pdf

版权声明:本文博客原创文章,博客,未经同意,不得转载。

自己主动机串标:Directed Acyclic Word Graph的更多相关文章

  1. [POJ 1204]Word Puzzles(Trie树暴搜&amp;AC自己主动机)

    Description Word puzzles are usually simple and very entertaining for all ages. They are so entertai ...

  2. HDOJ 5421 Victor and String 回文串自己主动机

    假设没有操作1,就是裸的回文串自己主动机...... 能够从头部插入字符的回文串自己主动机,维护两个last点就好了..... 当整个串都是回文串的时候把两个last统一一下 Victor and S ...

  3. hdoj 2222 Keywords Search 【AC自己主动机 入门题】 【求目标串中出现了几个模式串】

    Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others ...

  4. hdu5384 AC自己主动机模板题,统计模式串在给定串中出现的个数

    http://acm.hdu.edu.cn/showproblem.php?pid=5384 Problem Description Danganronpa is a video game franc ...

  5. Hdu 3341 Lost&#39;s revenge (ac+自己主动机dp+hash)

    标题效果: 举个很多种DNA弦,每个字符串值值至1.最后,一个长字符串.要安排你最后一次另一个字符串,使其没事子值和最大. IDEAS: 首先easy我们的想法是想搜索的!管她3721..直接一个字符 ...

  6. Hdu 3962 Microgene (AC自己主动机+矩阵)

    标题效果: 构造一个字符串,使得有两个和两个以上的目标串.长短L这一系列有多少串都. IDEAS: 只有全款减有1一些字符串,没有目标就是答案. 假定数据是非常小的,够用dp解.dp[i][j][k] ...

  7. Codeforces 86C Genetic engineering (AC自己主动机+dp)

    题目大意: 要求构造一个串,使得这个串是由所给的串相连接构成,连接能够有重叠的部分. 思路分析: 首先用所给的串建立自己主动机,每一个单词节点记录当前节点可以达到的最长后缀. 開始的时候想的是dp[i ...

  8. Hdu 2457 DNA repair (ac自己主动机+dp)

    题目大意: 改动文本串的上的字符,使之不出现上面出现的串.问最少改动多少个. 思路分析: dp[i][j]表示如今 i 个字符改变成了字典树上的 j 节点. 然后顺着自己主动机一直转移方程. 注意合法 ...

  9. 字符串算法之 AC自己主动机

    近期一直在学习字符串之类的算法,感觉BF算法,尽管非常easy理解,可是easy超时,全部就想学习其它的一些字符串算法来提高一下,近期学习了一下AC自己主动机.尽管感觉有所收获,可是还是有些朦胧的感觉 ...

随机推荐

  1. 50 tips of JavaScript

    50 tips of JavaScript,这些坑你都知道吗? 1.在局部作用域中,使用var操作符定义的变量将成为定义该变量的作用域中的局部变量,省略var的会创建全局变量:在全局作用域中,不管是否 ...

  2. k-d tree算法

    k-d树(k-dimensional树的简称),是一种分割k维数据空间的数据结构.主要应用于多维空间关键数据的搜索(如:范围搜索和最近邻搜索). 应用背景 SIFT算法中做特征点匹配的时候就会利用到k ...

  3. 读书笔记:《为什么大猩猩比专家高明, How We Decide》

    读书笔记:<为什么大猩猩比专家高明, How We Decide> 英文的书名叫<How We Decide>,可能是出版社的原因,非要弄一个古怪的中文书名<为什么大猩猩 ...

  4. WampServer:轻松配置Wordpress安装环境

    WordPress运行环境 PHP 5.2.4 或更新版本(不支持第三方推出的“PHP 6.0”) MySQL 5.0 或更新版本 Apache mod_rewrite 模块(可选,用于支持“固定链接 ...

  5. 局部权重线性回归(Locally weighted linear regression)

    在线性回归中,因为对參数个数选择的问题是在问题求解之前已经确定好的,因此參数的个数不能非常好的确定,假设參数个数过少可能拟合度不好,产生欠拟合(underfitting)问题,或者參数过多,使得函数过 ...

  6. 【JAVA得知】struts2 于 Actionsupport 任务

    尊重原创:http://xumiao900.iteye.com/blog/469760     Action 跟 Actionsupport 的差别      当我们在写action的时候,能够实现A ...

  7. 我的Android进阶之旅------>经典的大牛博客推荐(排名不分先后)!!

    本文来自:http://blog.csdn.net/ouyang_peng/article/details/11358405 今天看到一篇文章,收藏了很多大牛的博客,在这里分享一下 谦虚的天下 柳志超 ...

  8. jconsole线程面板中的阻塞总数和等待总数(转)

    阻塞总数 Blocked count is the total number of times that the thread blocked to enter or reenter a monito ...

  9. Java并发编程(您不知道的线程池操作)

    Java并发编程(您不知道的线程池操作) 这几篇博客,一直在谈线程,设想一下这个场景,如果并发的线程很多,然而每个线程如果执行的时间很多的话,这样的话,就会大量的降低系统的效率.这时候就可以采用线程池 ...

  10. 为什么不要在android或者ios上直连mysql或者sqlserver之类的数据库(跳大神)

    很多同学 都有直连这些数据库的想法,假设我说了下面二个问题之后你还想直连,那我也没办法 数据库是一个服务端最重要的部分,也是最脆弱的部分,更是最敏感的部分 假设直连会造成例如以下问题 1.安全问题,你 ...