zoukankan      html  css  js  c++  java
  • 序列自动机

    简述

      序列自动机是一个能快速判断一个串t是否为另一个串s的子序列的算法。对于串s构造序列自动机,本质上就是预处理出一个nxt[][]数组,nxt[i][j]代表从第i个位置开始,字符j出现的第一个位置的下一个位置。

    代码详解

    构造

      复杂度O(lens)

      对于nxt数组的构造本质上就是一个dp的过程,len位置就是最后一个位置+1,所以我们设置一个末边界为inf,往前递推对于之后的每个位置该位置的字符的nxt值就是i+1,其他字符就是nxt[i+1]的值。

    void init(char *s){
        int len=strlen(s);
        for(int i=0;i<26;i++) nxt[len][i]=inf;
        for(int i=len-1;i>=0;i--){
            for(int j=0;j<26;j++){
                nxt[i][j]=nxt[i+1][j];
            }
            nxt[i][s[i]-'a']=i;
        }
    }

     查询

      复杂度O(lent)

      对于串t,我们可以利用nxt数组,pos指针初始化为0,pos就是开始查找的下标,每次令pos=nxt[pos][当前字符],也就是匹配字符的后一个位置=下一个开始找的位置,当pos=inf时证明在pos位置开始后面没有所需字符了,所以不是子序列。

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

    模板

    void init(char *s){
        int len=strlen(s);
        for(int i=0;i<26;i++) nxt[len][i]=inf;
        for(int i=len-1;i>=0;i--){
            for(int j=0;j<26;j++){
                nxt[i][j]=nxt[i+1][j];
            }
            nxt[i][s[i]-'a']=i;
        }
    }
    bool find(char *t){
        int len=strlen(t);
        int pos=-1;
        for(int i=0;i<len;i++){
            pos=nxt[pos+1][t[i]-'a'];
            if(pos==inf) return 0;
        }
        return 1;
    }
    View Code
  • 相关阅读:
    c语言 判断文件是否存在
    lua 二进制函数使用
    linux sort 多列正排序,倒排序
    free命令学习 输出理解
    nginx 配置实现逻辑预算
    nginx 使用ctx实现数据共享,修改上下文
    lua中的数学库
    tornado文件上传实例
    ajax技术初识与应用
    web框架--XSS攻击和CSRF请求伪造
  • 原文地址:https://www.cnblogs.com/qq2210446939/p/12683119.html
Copyright © 2011-2022 走看看