后缀自动机模板

后缀自动机SAM详解
本文分享了一份关于后缀自动机(SAM)的学习笔记代码实现。该代码详细展示了如何使用C++实现后缀自动机,包括状态节点的定义、添加字符、构建后缀自动机、获取输出等核心功能。

@(学习笔记)[后缀自动机]
不想写了.
贴一份代码吧.

#include <cstdio>
#include <cstring>

struct suffixAutomaton
{
    const int ORG = 'A';
    
    struct state
    {
        int stp;
        state *pre, *suc[1 << 5];

        inline state(int _stp = 0)
        {
            stp = _stp;
            pre = NULL;
            memset(suc, NULL, sizeof(suc));
        }
    };

    state *lst, *s;

    inline void add(int c)
    {
        state *u = new state(lst->stp + 1), *p = lst;

        for(; p != NULL && p->suc[c] == NULL; p = p->pre)
            p->suc[c] = u;

        if(p == NULL)
            u->pre = s;
        else
        {
            state *q = p->suc[c];

            if(p->stp + 1 == q->stp)
                u->pre = q;
            else
            {
                state *v = new state(p->stp + 1);
                memcpy(v->suc, q->suc, sizeof(q->suc));
                v->pre = q->pre;
                q->pre = u->pre = v;

                for(; p != NULL && p->suc[c] == q; p = p->pre)
                    p->suc[c] = v;
            }
        }
        
        lst = u;
    }

    inline void build(char *str, int len)
    {
        lst = s = new state;

        for(int i = 0; i < len; ++ i)
            add(str[i] - ORG);
    }

    char str[1 << 5];

    inline void dfs(state *u, int len)
    {
        for(int i = 0; i < 26; ++ i)
            if(u->suc[i] != NULL)
            {
                str[len ++] = i + ORG;
                
                for(int i = 0; i < len; ++ i)
                    putchar(str[i]);
                
                putchar('\n');
                
                dfs(u->suc[i], len);
                -- len;
            }
    }

    inline void getOutput()
    {
        memset(str, 0, sizeof(str));
        dfs(s, 0);
    }
}sam;

int main()
{
    freopen("sam.in", "r", stdin);
    freopen("sam.out", "w", stdout);

    char s[1 << 5];
    scanf("%s", s);
    
    sam.build(s, strlen(s));
    sam.getOutput();
}

转载于:https://www.cnblogs.com/ZeonfaiHo/p/6616097.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值