美文网首页
AC自动机_重叠与非重叠匹配

AC自动机_重叠与非重叠匹配

作者: Gitfan | 来源:发表于2017-08-01 15:53 被阅读0次
  • 可重叠与不可重叠匹配
      比如模式串为aba,字符串为abababab,若可重叠匹配,那么aba出现的次数为三次;若为不可重叠匹配,那么出现的次数为两次: aba / b / aba /b
       AC自动机对于可重叠匹配很方便,直接顺着节点的fail指针一直走就可以.

不可重叠匹配
Searching the String
题意:
有若干个模式串,然后在字符串中查询它们出现的次数.但是0表示可以重叠出现,1表示不可以重叠出现;
题解:
 假设字典树的每个单词尾节点都有个变量为pos,记录最后一次匹配主串的位置;
 对于可重叠匹配,直接顺着自动机的fail指针一直走;
 对于不可重叠匹配,如果当前正在匹配主串的位置-最后一次成功匹配的字符串的位置大于等于单词的长度,那么这样的匹配是可行的;
 比如模式串为aba,字符串为abababab,第一次匹配到aba的位置为2;第二次匹配到aba位置为4,但是4-2<3,所以这次的匹配是无效的;第三次匹配到aba位置为6,6-2=4>=3,成功匹配;所以最后成功匹配次数为2

/*    这题数据有点恶心,模式串会重复出现
input:
ab
4  
0 ab  
1 ab  
0 ab  
1 ab  
output:
Case 1
1
1
1
1

*/  
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
const int MAXN=100010;
const int BASE=26;
struct Node
{
    int fail;
    int next[26];
    bool ed;
    int len;
    int id1;
    int id2;
    int pos;
    void init()
    {
        fail=0;
        ed=false;
        len=pos=-1;
        id1=id2=0;
        memset(next,0,sizeof(next));
    }
};
Node trie[600005];
int trie_s;
int *x[MAXN];
char str[MAXN];
void put(char *str,int choose,int id)
{
    int p=1;
    int len=strlen(str);
    for(int i=0;i<len;i++)
    {
        int pos=str[i]-'a';
        if(trie[p].next[pos]==0)
        {
            trie[p].next[pos]=++trie_s;
            trie[trie_s].init();
        }
        p=trie[p].next[pos];
    }
    trie[p].ed=true;
    trie[p].len=len;
    if(choose==0)
    {
        x[id]=&(trie[p].id1);
    }
    else x[id]=&(trie[p].id2);
}
void getFail()
{
    queue<int> que;
    int son,p=1,temp;
    que.push(p);
    while(!que.empty())
    {
        int curr=que.front();
        que.pop();
        for(int i=0;i<26;i++)
        {
            son=trie[curr].next[i];
            if(son)
            {
                if(curr==1) trie[son].fail=1;
                else
                {
                    temp=trie[curr].fail;
                    while(temp!=0)
                    {
                        if(trie[temp].next[i])
                        {
                            trie[son].fail=trie[temp].next[i];
                            break;
                        }
                        temp=trie[temp].fail;
                    }
                    if(temp==0) trie[son].fail=1;
                }
                que.push(son);
            }
        }
    }
}
void query(char *str)
{
    int len=strlen(str);
    int p=1,temp;
    for(int i=0;i<len;i++)
    {
        int pos=str[i]-'a';
        while(!trie[p].next[pos]&&p!=1) p=trie[p].fail;
        p=trie[p].next[pos];
        if(p==0) p=1;
        temp=p;
        while(temp!=1)
        {
            if(trie[temp].ed)
            {
                trie[temp].id1=trie[temp].id1+1;
                if(trie[temp].pos==-1||(i-trie[temp].pos>=trie[temp].len))
                {
                    trie[temp].id2=trie[temp].id2+1;
                    trie[temp].pos=i;
                }
            }
            temp=trie[temp].fail;
        }
    }
}
int main()
{
    int n,choose,cas=1;
    char ss[10];
    while(scanf("%s",str)!=EOF)
    {
        scanf("%d",&n);
        trie[1].init();
        trie_s=1;
        for(int i=1;i<=n;i++)
        {
            scanf("%d %s",&choose,ss);
            put(ss,choose,i);
        }
        getFail();
        query(str);
        printf("Case %d\n",cas++);
        for(int i=1;i<=n;i++)
        {
            printf("%d\n",*x[i]);
        }
        printf("\n");
    }
    return 0;
}

相关文章

  • AC自动机_重叠与非重叠匹配

    可重叠与不可重叠匹配比如模式串为aba,字符串为abababab,若可重叠匹配,那么aba出现的次数为三次;若为不...

  • AC 自动机

    AC自动机 AC自动机是一个经典的多模式串匹配算法,它可以实现对主串的一次扫描来匹配多个模式串的功能。实现AC自动...

  • re.findall()函数使用

    re.findall(pattern, string, flags=0) 返回string中所有非重叠的匹配——字...

  • graph&networks

    问题与概念域: { 重叠社区,非重叠社区,nested nodes 属于多个 communities 如何生成 g...

  • Python正则表达式

    方法归纳 方法描述findall将字符串中所有的非重叠匹配模式以列表形式返回finditer与findall类似,...

  • AC自动机 专题整理

    AC自动机学习记录 参考资料 字典树(讲解+模版)AC自动机算法AC自动机算法详解hdu 2222 ac自动机入门...

  • AC自动机

    参考资料:AC自动机GIF动图(来自油管) 以下文章节选自:王争老师 AC自动机:如何用多模式串匹配实现敏感词过滤...

  • AC自动机 - 过滤敏感词

    今天我们学习一种多模式匹配算法:AC自动机。(这个名字可能不太严谨,自动机知识这个算法的一个部分)多模式匹配算法:...

  • 重叠【非真实05】

    我时常做一个梦:F街上有一间房子,在梦里,反复的告诉我那间房子将来要是我的。 关于那个地点,我只知道我小时候的确是...

  • [LeetCode] Overlapping/Non-Overl

    LeetCode里面关于Overlapping/Non-Overlapping的主要有一下几类: 寻找重叠/非重叠...

网友评论

      本文标题:AC自动机_重叠与非重叠匹配

      本文链接:https://www.haomeiwen.com/subject/zavjlxtx.html