java自动机字符串匹配_【数据结构】自动机用于多个目标字符串的匹配查找

后缀自动机在trie数基础上,引入了父节点parent,前缀nxt,后续child[],匹配单词数量cnt,其中child[i]为当前字符串遇到char i时跳转到的节点。

以下内容可以用bfs由浅入深初始化自动机。这个过程类似kmp,我觉得不同在于kmp不保存每一个节点遇到任意字母后跳转位置,而只保存它与前缀串(nxt)匹配位置

如下:

注意n#parent已经初始化完成。

if n#parent!=root(即n#parent#nxt!=n#parent)

n#nxt=node[n#parent#nxt].child[n#idx]

if n#child[i]==null

n#child[i]=node[n#nxt]->child[i]

n#cnt+=node[n#nxt].cnt

#include

#include

#include

#include

#define MAXLEN 1100000

#define CHILDCNT 26

using namespace std;

struct Node{

int idx;

int nxt;

int pnt;

int child[CHILDCNT];

int cnt;// words matched

void init(int parent,int childIdx){

idx=childIdx;

nxt=0,pnt=parent,cnt=0;

memset(child,sizeof(child));

}

};

struct TrieG{

//int root=0;

Node nodes[MAXLEN];

int lst;

TrieG(){

lst=0;

nodes[lst++].init(0,0);

}

string print(int i){

if(i==0) return "";

Node &n=nodes[i];

char c='a'+n.idx;

return print(n.pnt)+c;

}

void add(char* s){

int v=0;

int len=strlen(s);

for(int i=0;i

int of=s[i]-'a';

if(!nodes[v].child[of]){

nodes[v].child[of]=lst;

nodes[lst].init(v,of);

lst++;

}

v=nodes[v].child[of];

if(i==len-1) nodes[v].cnt++;

}

}

int init(){

// nxt[0]=0,nxt[nodes[0].child[]]=0

queueque;

que.push(0);

while(!que.empty()){

int v=que.front();que.pop();

Node &n=nodes[v];

for(int i=0;i

if(n.child[i])

que.push(n.child[i]);

}

if(v>0) {

if(n.pnt>0) n.nxt=nodes[nodes[n.pnt].nxt].child[n.idx];

n.cnt+=nodes[n.nxt].cnt;

for(int i=0;i

if(!n.child[i])

n.child[i]=nodes[n.nxt].child[i];

// cout<child["<

}

}

}

}

bool match(char *s){

int len=strlen(s);

int v=0;

int count=0;

for(int i=0;i

v=nodes[v].child[s[i]-'a'];

if(nodes[v].cnt) return true;

}

return false;

}

};

int main(){

TrieG g;

// char *s[11]={"abcd","bcd","cd","d","abce","abef","abcdefg","a","ab","abc","abcd"};

int n;cin>>n;

char buf[1000001];

for(int i=0;i

cin>>buf;

g.add(buf);

}

g.init();

cin>>buf;

bool res=g.match(buf);

if(res) cout<

else cout<

return 0;

}

相关文章

总结

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。

如您喜欢交流学习经验,点击链接加入交流1群:1065694478(已满)交流2群:163560250

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值