在学习和了解序列自动机前,我们要熟悉自动机,“自动机”一般都指“确定有限状态自动机”。自动机是计算机科学中被广泛使用的一个数学模型,其思想在许多字符串算法中都有涉及,因此推荐在学习一些字符串算法(KMP、AC 自动机、SAM)前先完成自动机的学习。学习自动机有助于理解上述算法。

在这就不详细重复说明自动机了,接下来就是序列自动机的内容。

序列自动机是一个可以快速判断字符串t是否是字符串s的子串的一个算法。使用空间复杂度来换取时间复杂度。


构造

对字符串s构造序列自动机,使用nxt数组。nxt[i][j]代表从第i个位置开始,字符j出现的第一个位置。我们倒着遍历更新即可。

    int nxt[N][27];
    void init(char *s){
        int l=strlen(s);
        for(int i=0;i<26;i++) 
            nxt[l][i]=INF;//初始化
        for(int i=l-1;i>=0;i--){
            for(int j=0;j<26;j++){
                nxt[i][j]=nxt[i+1][j];
            }
            nxt[i][s[i]-'a']=i;//apple nxt[4]['e'-'a']=4
        }
    }

查询

设置初始指针p为-1,每次让p跳到nxt[p+1][j]上面,j为当前查询的字符,如果p为INF,则说明找不到下一个字符,即t不是s的子串。

bool find(char *t){
        int pos=-1;
        int l=strlen(t);
        for(int i=0;i<l;i++){
            pos=nxt[pos+1][t[i]-'a'];
            if(pos==INF) return 0;
        }
        return 1;
}


点赞(0)

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

Dotcpp在线编译      (登录可减少运行等待时间)