zoukankan      html  css  js  c++  java
  • AC自动机总结

    AC自动机总结

    自动机的概念:

    自动机又称有限状态自动机,是从初始状态不断接受输入,根据输入数据和当前状态跳转到下一状态的一种机器。

    (AC)自动机可以实现多串匹配单串。复杂度是(O(sum n+m)),也就是模式串总长+文本串长。
    (AC)自动机匹配失配时,类似(KMP)算法的(next)数组,(AC)自动机上有(fail)指针可以跳到下一个应该进行匹配的状态。
    (fail)指针的一般定义是:沿着父亲的(fail)指针一直向上跳,直到跳到某一个节点,这个节点拥有与自己相同字母的子节点,那么(fail)指针就指向这个相同字母的子节点。
    一般写起来是这样的

    void Get_Fail()
    {
    	for (int i=0;i<26;i++) if (ch[i][0]) Q.push(ch[i][0]);
    	while (!Q.empty())
    	{
    		int u=Q.front();Q.pop();
    		for (int i=0;i<26;i++)
    			if (ch[i][u]) fail[ch[i][u]]=ch[i][fail[u]],Q.push(ch[i][u]);
    			else ch[i][u]=ch[i][fail[u]];
    	}
    }
    

    这样相当于建出了一个(Trie)图,使得每个节点都拥有了(26)个儿子。如果你想要保存原(Trie)树的话请先备份。
    一般来说插入一个模式串就是

    void Insert(string c,int ID)
    {
    	int l=c.length(),x=0;
    	for (int i=0;i<l;i++)
    	{
    		if (!ch[c[i]-'a'][x]) ch[c[i]-'a'][x]=++tot;
    		x=ch[c[i]-'a'][x];
    	}
    	id[x]=ID;
    }
    

    然后因为(AC)自动机本身就和“状态”关系密切,所以(AC)自动机上往往会用来跑(DP)
    然后如果你不记得(KMP)怎么写了也可以写(AC)自动机。

    几个小tips

    如果是给出若干个串求匹配,由(fail)指针串起来的点是一个点,意思是如果你匹配了一个串,那么你同时也匹配了这个串的任意后缀。所以你在(AC)自动机上每走过一个点,就要暴跳(fail)(root)进行匹配。
    但如果是给出若干不合法串求合法方案数,这时由(fail)指针串起来的点就不是一个点,因为假使认为是同一个点会导致不合法状态计入。同时,不合法标记要沿着(fail)下传,意思是如果某一个串不合法,那么以这个串为前缀的任意串都不合法。

    这是我的水表

  • 相关阅读:
    解决“已禁用对分布式事务管理器(MSDTC)的网络访问”错误
    C# Freely convert between IList<T> and IEnumerable<T>
    Json MaxJsonLength Error
    [转]Introducing the IE8 Developer Tools JScript Profiler
    页面调试心得
    ASP.NET中Label控件特殊之处
    模板模式
    Android中通过typeface设置字体
    Android 新浪微博授权
    【转】android:网络图片转为bitmap 保存至SD卡中
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/8343863.html
Copyright © 2011-2022 走看看