序列化自动机

这种算法用于查找子序列,与之比较像的KMP用来查找子串。两者都提供了高效的查找。

模板题:https://ac.nowcoder.com/acm/contest/20960/1033

算法思想:假设母序列为s1,我们可以把s1的每个字符后面的每种字母出现的第一个位置用nxt数组记录下来,要是哪种字母不存在就标记为-1. 为了实现这个想法,我们可以倒序遍历s1。若当前遍历到的字母下标为i,用last数组记录s1[i]的位置,遍历到第i-1个字母时,last存放的就是字母i的位置。

当我们要查找子序列s2时,假设s2是"morty",就可以直接通过nxt[m][o]获得s1中m后面o的第一个位置。

#include<iostream>
#include<cstring>
using namespace std;
int nxt[1000010][26];
int last[26];
int main(){
    memset(last,-1,sizeof(last));    //初始化last全为-1,代表最后一个字符后面没有字符
    string s1;
    cin>>s1;
    int n=s1.size();
    for(int i=n-1;i>=0;i--){        
        for(int j=0;j<26;j++){
            nxt[i][j]=last[j];        //记录s1[i]后面每种字母的位置
        }
        last[s1[i]-'a']=i;            //更新last
    }
    int x;
    cin>>x;
    while(x--){
        string s2;cin>>s2;
        bool flag=1;
        int pos=last[s2[0]-'a'];    //子序列首字母位置
        if(pos==-1) {
            cout<<"No"<<endl;
            continue;
        }
        for(int i=1;i<s2.size();i++){
            pos=nxt[pos][s2[i]-'a'];    //获得下一个字母位置
            if(pos==-1){
                cout<<"No"<<endl;
                flag=0;
                break;
            }
           
        }
        if(flag) cout<<"Yes"<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lorry_521

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值