月月查华华的手机 (序列自动机(查找一个字符串里有没有一个子序列是另一个字符串))

本文介绍了一种使用序列自动机解决子序列问题的方法,并提供了一个详细的C++实现示例。该方法通过预处理字符串来快速判断一个字符串是否是另一个字符串的子序列。

 

序列自动机:next[i][j]  表示在原串s第i位后面的第一个j出现的位置,设串长为n,字符集大小为a,预处理时间复杂度为O(n*a),代码如下

链接:https://ac.nowcoder.com/acm/contest/392/J

题意:给你一个字符串A,和m个字符串s[i]  

问s[i] 是否是A的一个子序列

 

序列自动机模板题

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#define ll long long
const int maxn = 1e6+5;
using namespace std;
char A[maxn],s[maxn];
int nextc[maxn][27],m;
int main()
{
    scanf("%s",A+1);
    int n = strlen(A+1);
    for(int i=n;i>0;i--) {
        for(int j=0;j<26;j++) {
            nextc[i-1][j]=nextc[i][j];
        }
        nextc[i-1][A[i]-'a']=i;
    }
    scanf("%d",&m);
    while(m--) {
        scanf("%s",s);
        int len = strlen(s),flag=1;
        for(int i=0,now=0;i<len;i++) {
            now = nextc[now][s[i]-'a'];
            if(now == 0) {
                flag=0;
                break;
            }
        }
        if(flag) {
            printf("Yes\n");
        }else printf("No\n");
    }
    return 0;
}


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值