KMP && AC自动机模板

KMP:

获得next数组:

void getNext()
{
    nxt[0] = -1;
    for(int i = 1; i < n; i++)
    {
        int p = nxt[i-1];
        for(; p != -1 && str[p+1] != str[i]; p = nxt[p]);
        p = str[p+1] == str[i] ? p+1 : -1;
        nxt[i] = p;
    }
}

KMP匹配:返回母串上与子串匹配的第一个位置的起始处

int kmp()
{
    int i = 0, j = 0;
    for(; i < n; )
    {
        if(str[i] == pat[j])
        {
            i++;
            j++;
            if(j == m) return i-m+1;
        }
        else
        {
            if(j == 0) i++;
            else
            {
                j = nxt[j-1]+1;
            }
        }
    }
    return -1;
}

AC自动机:

class Node
{
public:
    int next[30], fail;
    int endCnt;
    void clear()
    {
        memset(next, 0, sizeof next);
        endCnt = 0;
        fail = 0;
    }
};
Node node[N];
class Trie
{
public:

    int root, cnt;
    void init()
    {
        cnt = 0;
        root = newNode();
        node[0].clear();
    }

    int newNode()
    {
        node[++cnt].clear();
        return cnt;
    }

    void ins(char str[], int len)
    {
        int p = root;
        for(int i = 0; i < len; i++)
        {
            int cur = str[i]-'A';
            if(!node[p].next[cur])
            {
                node[p].next[cur] = newNode();
            }
            p = node[p].next[cur];
        }
        node[p].endCnt++;
    }

    void build()
    {
        queue<int> q;
        q.push(root);

        while(!q.empty())
        {
            int cur = q.front();
            q.pop();
            for(int i = 0; i < 26; i++)
            {
                int nxt = node[cur].next[i];
                if(nxt)
                {
                    int p = node[cur].fail;
                    for(; p != 0 && node[p].next[i] == 0; p = node[p].fail);
                    p = p == 0 ? root : node[p].next[i];
                    node[nxt].fail = p;
                    q.push(nxt);
                }
            }
        }
    }
	int match(char str[], int len)
	{
		int p = root, res = 0;
		for(int i = 0; i < len; i++)
		{
			int cur = str[i]-'A';
			for(; p && node[p].next[cur] == 0; p = node[p].fail);
			p = p ? node[p].next[cur] : root;
			int tp = p;
			for(; tp && node[tp].endCnt > 0; tp = node[tp].fail)
			{
				res += node[tp].endCnt;
				node[tp].endCnt = 0;
			}
		}
		return res;
	}
};


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值