算法——序列自动机

安时积分法和开路电压法结合估算锂电池SOC 基于安时积分法和开路电压法结合的锂电池SOC估计Simulink仿真建模,利用安时积分法计算放电过程中的SOC,在搁置状态利用开路电压法进行SOC修正。 阅读详情

序列自动机是一种用于高效判断一个字符串是否为另一个字符串的子序列的数据结构。其核心思想是通过预处理目标字符串,构建状态转移表,从而在O(1)时间复杂度下支持多次子序列查询。


1. 核心概念

  • 子序列定义:若字符串sub可以通过删除字符串s中的某些字符(不改变顺序)得到,则称sub是s的子序列。例如,"ace"是"abcde"的子序列。
  • 应用场景:文本编辑器中的快速输入提示、基因序列匹配、日志分析等。

2. 构建方法

预处理步骤:

  1. 初始化数组:创建一个二维数组next[i][c],表示在字符串s的位置i之后,字符c下一次出现的位置。
  2. 逆序填充:从字符串末尾向前遍历,记录每个位置之后各字符的最近位置。

示例(以字符串s = "abcab"为例):

位置: 0 1 2 3 4
字符: a b c a b

next数组(部分):
next[0]['a'] = 3
next[0]['b'] = 1
next[0]['c'] = 2
...
  • 当在位置0时,下一个a出现在位置3,下一个b在位置1,c在位置2。

3. Java代码实现

public class SubsequenceAutomaton {
    private int[][] next; // next[i][c]: 位置i后字符c的下一个位置

    public SubsequenceAutomaton(String s) {
        int n = s.length();
        int CHAR_SET_SIZE = 256; // 假设处理ASCII字符

        next = new int[n + 1][CHAR_SET_SIZE];
        Arrays.fill(next[n], -1); // 末尾位置无后续字符

        // 逆序填充next数组
        for (int i = n - 1; i >= 0; i--) {
            System.arraycopy(next[i + 1], 0, next[i], 0, CHAR_SET_SIZE);
            next[i][s.charAt(i)] = i + 1; // 记录当前字符的位置
        }
    }

    // 判断sub是否是s的子序列
    public boolean isSubsequence(String sub) {
        int pos = 0;
        for (char c : sub.toCharArray()) {
            pos = next[pos][c];
            if (pos == -1) return false;
        }
        return true;
    }

    public static void main(String[] args) {
        String s = "abcab";
        SubsequenceAutomaton automaton = new SubsequenceAutomaton(s);

        System.out.println(automaton.isSubsequence("ab")); // true
        System.out.println(automaton.isSubsequence("acb")); // false(顺序不匹配)
        System.out.println(automaton.isSubsequence("aba")); // true
    }
}

4. 复杂度分析

  • 预处理时间:O(n * |Σ|),其中n为字符串长度,|Σ|为字符集大小(如ASCII为256)。
  • 查询时间:O(m),m为子序列长度。
  • 空间复杂度:O(n * |Σ|)。

5. 优化与扩展

  1. 动态字符集支持:

    • 若处理Unicode字符(如中文),需使用HashMap替代数组,但会牺牲部分性能:
      List<Map<Character, Integer>> next = new ArrayList<>();
      
  2. 空间优化:

    • 对于长字符串,可改用延迟构建或压缩状态,但会增加查询时间。
  3. 多模式匹配:

    • 结合AC自动机,支持同时匹配多个子序列。

6. 常见问题解答

Q1:如何处理中文字符?

  • Java中char为UTF-16编码,可直接处理大部分Unicode字符。若字符超出基本多文种平面(BMP),需使用codePoint方法。

Q2:与KMP算法有何区别?

  • KMP用于子串匹配(连续),而序列自动机用于子序列匹配(非连续)。

Q3:是否支持动态更新目标字符串?

  • 传统实现不支持,需重新构建自动机。可研究增量更新算法。

通过序列自动机,可显著提升子序列匹配效率,适用于需要频繁查询的场景。根据实际需求调整字符集处理方式,平衡时间与空间复杂度。

【机器学习】随机森林(Random Forest,简称 RF):预测光伏电站功率 || 缺失数据处理 || 重复行处理... 【机器学习】随机森林(Random Forest,简称 RF):预测光伏电站功率。 阅读详情

相关推荐

字符串替换—牛客网(C++实现)

一.题目描述 请你实现一个简单的字符串替换函数。原串中需要替换的占位符为"%s",请按照参数列表的顺序一一替换占位符。若参数列表的字符数大于占位符个数。则将剩下的参数字符添加到字符串的结尾。 给定一个字符串A,同时给定它的长度n及参数字符数组arg,请返回替换后的字符串。保证参数个数大于等于占位符个数。保证原串由大小写英文字母组成,同时长度小于等于500。 测试样例: “A%sC%sE”,7,[‘...

qq_38358582的博客 1522

序列自动机

目录 序列自动机 构造 查询 例题 序列自动机 序列自动机是一个可以快速判断字符串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++)

qq_45785407的博客 875

Linux音频调试实战:ALSA架构与tinymix工具的高级应用技巧

本文深入探讨了Linux音频调试的核心技术,重点解析了ALSA架构下音频信号的路由与混合机制。通过介绍轻量级命令行工具tinymix的高级应用技巧,指导开发者如何精准排查无声、音量异常、多路音频共存等复杂问题,并分享编写自动化测试脚本以提升嵌入式及智能设备音频开发效率的实战方法。

weixin_29210727的博客 101

【学习笔记】简单字符串算法 —— 序列自动机

序列自动机是一个比后缀自动机简单的自动机。后缀自动机可以看神仙 xyz32768xyz32768xyz32768 的学习笔记:[学习笔记]省选数据结构·SAM 这个自动机同样是一个有限状态确定自动机,能够识别一个串的子序列。 即某个子序列对应到自动机上根到某个结点的一条路径。 自动机一共 n+1n+1n+1 个结点,每个位置开一个结点,加上一个根结点。 每个结点的符号为 ccc 的出边指向序列中...

changle_cyx 569

ComfyUI工作流换脸节点报错ReActorFaceSwap

找到自己ComfyUI安装目录的custom_nodes下是否有这个comfyui-reactor-node-main。大家在借鉴别人工作流进行AI换脸的时候,如果遇到ReActorFaceSwap报错提示,莫慌,看我的,两步解决问题。这里千万注意不要嵌套文件夹,保证点击去这个文件就可以看到内置的配置文件!找到自己ComfyUI安装目录的facerestore_models。如果有这个文件,直接跳过,去下一步。如果没有,可以去Git官网下载。

qq_70810809的博客 9015

GraphRAG + Ollama 本地化部署实战:从零搭建知识图谱问答系统

本文详细介绍了如何在本地部署GraphRAG与Ollama,搭建一个完全自主可控的知识图谱问答系统。通过逐步指导环境配置、项目初始化、核心设置修改以及源码适配,成功将GraphRAG从依赖云端OpenAI API转向本地Ollama服务,并选用qwen2.5:7b和nomic-embed-text模型。该方案有效解决了数据隐私与持续API成本问题,特别适合中小企业构建内部知识库或智能客服系统。

x2y3z4a5b的博客 918

【BIT2021程设】9.礼物——子序列自动机

写在前面: 本系列博客仅作为本人十一假期过于无聊的产物,对小学期的程序设计作业进行一个总结式的回顾,如果将来有BIT的学弟学妹们在百度搜思路时翻到了这一条博客,也希望它能对你产生一点帮助(当然,依经验来看,每年的题目也会有些许的不同,所以不能保证每一题都覆盖到,还请见谅)。 不过本人由于学艺不精,代码定有许多不足之处,欢迎各位一同来探讨。 同时请未来浏览这条博客的学弟学妹们注意,对于我给出完整代码的这些题,仅作帮助大家理解思路所用(当然,因为懒,所以大部分题我都只给一个伪代码)。Anyway,请勿直接

敲代码的小潘的博客 651

大津法(OTSU)点云强度信息分割

大津法(OTSU)是一种灰度图像自适应的阈值分割方法,大津法根据图像的灰度分布,将图像分成背景和前景两部分,前景就是需要按照阈值分割出来的部分。由于点云的强度信息的特性,也可以利用此方法进行分类,但需要保证信息干扰较少,例如道路标线分割等场景较为适用。

qq_48694523的博客 965

序列自动机【模板】

序列自动机 算法分析 序列自动机实质还是用空间换时间,它有一个数组 ne[i][j]表示原串s的第i位后面那26个字符j出现的最早的 位置。 相当于建一棵树,根节点是一个空节点,它有26个孩子,表示每一个字母最早出现的位置 举个例子: s = “abcca” (默认数组下标为1-5) (a–z==0–25) ne[0][0] = 1,即字符串中出现的第一个字符’a’的位置为1 ne[1][1] = 2,即字符串距离下标1之后的字符’b’出现的第一个位置为2 以此类推我们可以得到 ne[1][0] =

满天星的博客 342

OsgEarth开发笔记(三):Osg3.6.3+OsgEarth3.1+vs2019x64开发环境搭建(下)

上一篇编译了proj6.2.0、gdal3.2.1,本篇继续。 OsgEarth的编译,是基于Osg和OsgEarth结合在一起的,先要编译Osg,然后编译OsgEarth。OsgEarth的依赖库较多,分为上、中、下三篇,然后单独有一篇如何将编译好的osgEarth集成到Qt中。

长沙红胖子 Qt・西安|省级科研团队从业背景,深耕双一流体系高精尖技术配套研发|剥离高精尖机理,沉淀高端特种行业领域 Qt 工程化落地经验|博文仅分享通用技术总结,输出公开普适工程思路。 4万+

Open3D (C++) 点云边界提取【2025最新版】

Compute the boundary points of a point cloud.The implementation is inspired by the PCL implementation. Reference:https://pointclouds.org/documentation/classpcl_1_1_boundary_estimation.html

点云侠的博客 871

子序列自动机 学习笔记

子序列自动机 学习笔记

glorious_dream的博客 1096

【人工智能】Spring AI项目在定义 `response_format` 的 Invalid schema for response_format ‘custom_schema‘

确保。

奶爸的编程之路,也就一周冷个三天 562

序列自动机算法(快速判断字符串是否是主串的一个子序列)

上面,j为当前查询的字符,如果最后找到了末尾那么就证明不是一个子序列。注意这里是判断是否是一个子序列(不连续)而不是子串(连续)序列自动机可以快速判断匹配串是否是模式串的子序列,代表从第i个位置开始,字符j出现的第一个位置。设置初始指针p为-1,每次让p跳到。构造序列自动机,使用。

wdnxmd的博客 313

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

7.19 ACM-ICPC字符串算法 序列自动机

序列自动机是一种针对字符串的简化版有限状态机。它主要用于快速查询一个字符串中是否存在某个特定的子序列。通过预处理输入字符串,构建一个状态转移表,序列自动机能够在常数时间内回答关于子序列的查询。序列自动机的每个状态对应字符串中的一个位置,状态间的转移由字符决定。对于每个状态,我们记录从该位置开始,每个字符下一次出现的位置。

tang7mj的博客 473

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

KMP算法,字符串哈希,最长公共子序列LCS,最长回文子序列LPS,AC自动机详细及模板

KMP算法能在线性时间内判定字符串A【1~N】是否为字符串V【1 ~M】的子串,并求出A在B中各次出现的位置. ·

m0_51678367的博客 498

【51Nod 2504】—是子序列的个数(序列自动机)

传送门 模板题 建出序列自动机之后暴力匹配即可 #include<bits/stdc++.h> using namespace std; const int RLEN=1<<20|1; inline char gc(){ static char ibuf[RLEN],*ib,*ob; (ob==ib)&&(ob=(ib=ibuf)+fread...

Stargazer的博客 332

2020.03.01日常总结兼子序列自动机略讲

【算法讲解】\color{green}{【算法讲解】}【算法讲解】 【模板链接】:\color{blue}{【模板链接】:}【模板链接】: 洛谷P5826 【模板】子序列自动机 【算法目标】:\color{blue}{【算法目标】:}【算法目标】: 【算法略讲】:\color{blue}{【算法略讲】:}【算法略讲】: 首先,我们来看看暴力如何完成这道题。很简单,拿一个指针,从头扫描到尾,单次...

ZHUYINGYE_123456的博客 272

CCF NOI Online 2021 提高组 T2 积木小赛 (子序列自动机+后缀自动机,O(n^2))

又是一次题目难度不保证递增的比赛

DD(XYX)的硫氰化氘博客 719

序列自动机学习

序列自动机一个可以n*(字符集)的复杂度预处理出字符串第i位及以后第一次出现大于字符j的位置 原理 if x>j dp[i][j]=i; else dp[i][j]=dp[i+1][j]; #include<iostream> #include<cstdio> #include<algorithm> #include<cmat...

canxuezhinuanyang的博客 324

模板:子序列自动机(字符串)

子序列自动机

BUG_Creater_jie的博客 639

P4584 [FJOI2015] 序列自动机 + AC 自动机 + SPFA

题意 传送门 P4584 [FJOI2015]带子串包含约束LCS问题 题解 分别对 X,YX,YX,Y 建序列自动机,那么可以从根节点搜索以遍历所有的公共子序列。对约束集子串建 ACACAC 自动机,搜索的同时更新子序列后缀状态。对约束集子串进行状态压缩,在 ACACAC 自动机 BFSBFSBFS 计算失配指针时,将各个节点对应的后缀状态记录所有的等于约束子集的后缀。最后 SPFASPFASPFA 求解最长子序列。 #include <algorithm> #include <cmat

neweryyy的博客 265

序列比对(26)精准匹配之KMP算法、Trie树以及AC自动机

前文已经介绍过KMP算法和Trie树,本文将在此基础上介绍AC自动机。 之前的序列比对文章大都在利用动态规划算法解决字符串的非精准匹配(允许错配、插入和缺失),比如全局比对和局部比对问题。当然,后来我们还介绍了模序发现和中间字符串问题,并初次学习了如何用分支定界法解决这一类问题。 既然有非精准匹配问题,就有精准匹配问题。所谓精准匹配,就是两个字符串在比对时,不允许错配、插入和缺失。其实,笔者之...

生信了 920

序列自动机:重复子序列问题

序列自动机:重复子序列问题 问题: 思路:   我们可以用序列自动机来判断子序列,如何处理A可重复的问题呢?我们并不需要真的重复A,当我们用序列自动机判断某个元素不存在时,A重复后该元素可能会出现(即该元素在遍历位置之前),因此我们重新回到位置1开始继续找寻该元素即可,同时重复次数+1   如何判断无论重复多少次都不可能为子序列?若A无论重复多少次,B都不会是A的子序列,则表明B中含有A中没有的字符(若B中的字符A中都有,则进行多次重复后,一定能在A中找到B中对应的字符)。那么如何判断B中是否含有A中没

qq_44709990的博客 467

P3728 曼哈顿序列 (序列自动机找第k小子序列)

题目连接 题面: #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #define ll long long #define llu unsigned ll //#define int ll using namespace std; const int maxn=10010

_Griefs 384

HDU 6586 String(序列自动机+贪心)

原题地址:http://acm.hdu.edu.cn/showproblem.php?pid=6586 题意:给出一个字符串str和k,以及一些限制条件,要求从选择str的一个子序列,使得满足限制条件,长度为k,且字典序最小。 思路:可以先通过构造一个序列自动机,这样子可以方便知道某个位置后任意字符的位置。 然后我们贪心的选取每一位,判断当前可不可行即可。 判断可不可行就是需要满足选择这个字母之后...

yiqzq的博客 533

[NOI Online 2021 提高组] 积木小赛——后缀自动机+子序列自动机

为什么这么多人都用哈希

偶耶的博客 386
上一篇: java——执行linux/cmd命令
下一篇: 算法——Manacher算法
夏子曦
夏子曦 优质创作者: 产品设计技术领域 优质创作者: 产品设计技术领域
博客等级 码龄15年 8289粉丝 427原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值