KMP算法 - 确定有限状态自动机

这篇具有很好参考价值的文章主要介绍了KMP算法 - 确定有限状态自动机。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

KMP神在哪里?

子串匹配问题,拍脑袋一下子想出来的暴力解法大抵都是两重for循环,不断重复扫描主串,与子串进行匹配,重复换句话讲就是冗余,会有很高的时间复杂度

我先前博客大作业发的模糊查找算法就是如此,我那里是在计算一个匹配度的问题,通过相同定位到相同字母判定开始计算相同字母的个数作为匹配度,多个判定点时,最终取最值。

而KMP通过对子串分析得到一个DFA(确定有限状态自动机)数组(后面简称dp数组),可以实现“移动”子串来与主串进行匹配,时间复杂度只需 O(N),也就是说只用遍历一遍主串!

关于DFA数组

什么是状态机

状态机(一般指有限状态机或有限状态自动机)是表示有限个状态以及在这些状态之间的转移和动作等行为的数学计算模型

状态机中有几个术语:state(状态) 、transition(转移) 、action(动作) 、transition condition(转移条件) 。

  • state(状态) :将一个系统离散化,可以得到很多种状态,当然这些状态是有限的。例如:门禁闸机可以划分为开启状态、关闭状态;电扇可以划分为关、一档、二档、三档等状态。

  • transition(转移) :一个状态接收一个输入执行了某些动作到达了另外一个状态的过程就是一个transition(转移)。定义transition(转移)就是在定义状态机的转移流程。

  • transition condition(转移条件) :也叫做Event(事件),在某一状态下,只有达到了transition condition(转移条件),才会按照状态机的转移流程转移到下一状态,并执行相应的动作。

  • action(动作):在状态机的运转过程中会有很多种动作。如:进入动作(entry action)[在进入状态时进行]、退出动作(exit action)[在退出状态时进行]、转移动作[在进行特定转移时进行]。

DFA状态机

我们这里的dp数组就是一个状态机

=> 二维数组 dp[ 状态 ][ 对应到子串中的字符时 ] = 转移到下一个状态

这里的“转移到下一个状态”就是对上面说的“移动”子串来匹配主串的实现

dp[j][c] = next
0 <= j < M,代表当前的状态
0 <= c < 256,代表遇到的字符(ASCII 码)
0 <= next <= M,代表下一个状态

dp[4]['A'] = 3 表示:
当前是状态 4,如果遇到字符 A,
pat 应该转移到状态 3

dp[1]['B'] = 2 表示:
当前是状态 1,如果遇到字符 B,
pat 应该转移到状态 2

如何构建Transition

下图为一个pat = “ABABC”的子串的状态转移图的构建

KMP算法 - 确定有限状态自动机

难点在于怎么让状态机确定回退到之前的哪个状态?

KMP算法强就强在它能尽可能少的回退

KMP算法 - 确定有限状态自动机

如何尽可能少的回退

我们记录一个X状态来标记遇到具体字符后 => 需要回退时,回退到哪个状态

这里对于X状态的标志有点动态规划的思想在里面 => 因为都是根据已知状态来得到新状态

X状态的更新很像匹配子子串

=> X也在匹配子串,X状态此刻匹配出的子串  具有  j状态此刻匹配出来最长相同部分(前缀)

甚至,还可以这样去理解X状态:有点像笔记本或备忘录,遇到类似情况可以复用些什么东西。这里就很像动态规划里的Memo文章来源地址https://www.toymoban.com/news/detail-485522.html

代码实现

#include <bits/stdc++.h>
using namespace std;

class KMP {
private:
    vector<vector<int>> dp;
    string pat;

public:
    KMP(string pat) {
        this->pat = pat;
        int sizePat = pat.size();
        dp.resize(sizePat, vector<int>(256, 0));
        int X = 0;
        dp[0][pat[0]] = 1;
        for(int j = 1; j < sizePat; j++) {
            for(int c = 0; c < 256; c++) {
                dp[j][c] = dp[X][c];
            }
            dp[j][pat[j]] = j + 1;
            X = dp[X][pat[j]];
        }
    }

    int Match(string txt) {
        int sizeTxt = txt.size(), sizePat = pat.size();
        int j = 0;
        for(int i = 0; i < sizeTxt; i++) {
            j = dp[j][txt[i]];
            if(j == sizePat) return i - sizePat + 1;
        }
        return -1;
    }
};

int main() {
    string pat, txt;
    cin >> txt >> pat;
    int index = KMP(pat).Match(txt);
    cout << index;
    return 0;
}

到了这里,关于KMP算法 - 确定有限状态自动机的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【元胞自动机】元胞自动机3D森林火灾模型【含Matlab源码 656期】

    【元胞自动机】元胞自动机3D森林火灾模型【含Matlab源码 656期】

    ✅博主简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,Matlab项目合作可私信。 🍎个人主页:海神之光 🏆代码获取方式: 海神之光Matlab王者学习之路—代码获取方式 ⛳️座右铭:行百里者,半于九十。 更多Matlab仿真内容点击👇 Matlab图像处理(进阶版) 路径规划

    2024年04月29日
    浏览(12)
  • AC自动机 模板

    核心思路是kmp的拓展,只是i++、j++什么的转换成了树的形式,初始化用bfs,每一点的初始化都是借助于该层以前的层进行的。 trie图优化: ne[t]是回溯一次,tr[ne[t]][i]直接记录好了它下一个点的位置,存在儿子就到儿子,没有儿子就是记录的回溯好的点。 每个点的ne都被计算

    2024年01月21日
    浏览(16)
  • AC 自动机学习笔记

    AC 自动机学习笔记

    AC自动机( (Aho Corasick Atomaton) )有着一种 (KMP) 的思想,所以在学习之前建议先学一下 (KMP) 。同时还需要了解一下 (Trie) 树(建议去看一下 oi-wiki 上的字典树) 给定一个字符串 (S) 和 (n) 模式串,问有多少个模式串在 (S) 中出现过。 首先我们把 (n) 个模式串组成一

    2024年02月11日
    浏览(10)
  • 「学习笔记」AC 自动机

    「学习笔记」AC 自动机

    点击查看目录 目录 「学习笔记」AC 自动机 算法 问题 思路 代码 例题 Keywords Search 玄武密码 单词 病毒 最短母串 文本生成器 背单词 密码 禁忌 前置:「学习笔记」字符串基础:Hash,KMP与Trie。 好像对例题的讲解越来越抽象了? 求 (n) 个单词在一个长度为 (m) 的文章里出现

    2024年02月02日
    浏览(12)
  • 元胞自动机(数学建模)

    元胞自动机(数学建模)

    一.元胞自动机的概念       元胞自动机(cellular automata,CA) 是一种时间、空间、状态都离散,空间相互作用和时间因果关系为局部的网格动力学模型,具有模拟复杂系统时空演化过程的能力。     元胞自动机是用一系列模型构造的 规则 构成,只要满足规则就可以算作是元胞

    2024年02月08日
    浏览(11)
  • 数学建模-元胞自动机

    数学建模-元胞自动机

    2024年02月14日
    浏览(13)
  • 【数学建模】元胞自动机

    元胞自动机(Cellular Automaton,简称CA) 元胞自动机(Cellular Automaton,简称CA)是一种离散空间和时间的计算模型。它由许多简单的计算单元(称为元胞)组成,每个元胞可以处于有限的状态之一。元胞自动机通过在空间上进行迭代更新的方式,根据元胞自身的状态和邻居元胞

    2024年02月15日
    浏览(14)
  • 数模笔记14-元胞自动机

    数模笔记14-元胞自动机

    元胞自动机理论 元胞自动机(Cellular Automata,CA)是一种时空离散的局部动力学模型,是研究复杂系统的一种典型方法,特别适合用于空间复杂系统的时空动态模拟研究。 元胞自动机不是由严格定义的物理方程或函数确定,而是用一系列模型构造的 规则 构成。凡是满足这些

    2024年02月09日
    浏览(12)
  • 100行python代码实现细胞自动机(康威生命游戏)

    100行python代码实现细胞自动机(康威生命游戏)

     英国数学家约翰·何顿·康威在1970年发明了细胞自动机,它属于一种仿真程序,通过设定一些基本的规则来模拟和显示的图像的自我进化,看起来颇似生命的出生和繁衍过程,故称为“生命游戏”。 完成效果 用到的第三方库 pygame 基本规则 康威生命游戏在网格上进行,有填

    2023年04月08日
    浏览(12)
  • 元胞自动机( Cellular Automata)研究 (Python代码实现)

    元胞自动机( Cellular Automata)研究 (Python代码实现)

     👨‍🎓 个人主页: 研学社的博客   💥💥💞💞 欢迎来到本博客 ❤️❤️💥💥 🏆博主优势: 🌞🌞🌞 博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️ 座右铭: 行百里者,半于九十。 📋📋📋 本文目录如下: 🎁🎁🎁 目录 💥1 概述 📚2 运行结果 🌈

    2024年02月09日
    浏览(11)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包