有限状态自动机

2023-10-27

1 什么是有限状态自动机

1.1什么是计算

维基百科定义计算(英语:Calculation)是一种将“单一或多个的输入值”转换为“单一或多个的结果”的一种思考过程。可以简单理解为给出一个问题得到一个答案的过程。如下图所示日常生活比较常见计算问题:
在这里插入图片描述

1.2 判定问题
维基百科定义:在可计算性理论与计算复杂性理论中,决定性问题,亦称判定问题,(英语:Decision problem)是一个在某些形式系统回答“是”或“否”的问题。
在可计算理论中,会把相关计算问题最终转化为判定问题,如下图所示,比如求正方形面积如何转成判定问题,边长为4的正方向面积,边长为4面积是1、2、3…输入到判定器去判断(可计算理论中不考虑性能)最终16时候判定器会接受。
在这里插入图片描述

1.3 有限状态自动机
维基百科给出的定义:有限状态机(finite state machine, FSM)又称为有限状态自动机(finite state automaton,FSA)简称状态机,是表示有限个状态以及在这些状态之间的转移和动作作为行为的数学计算模型。
从定义可以FSM是一个计算模型;它的状态是有限的(可枚举的),自动机是这个状态之间的转移行为,最后的结果判断这一系列行为是否符可接受要求。
有限状态自动机的数学模型,五元组M=(S,I,f,A,S0),其中
● S是一个有限的状态集合
● I是一个有限输入符号结合
● f表示状态的转换是从SXI到S的函数
● A表示接受状态非空集合A包含于S
● S0表示初始状态,S0属于S
起初,这个自动机处于「初始状态」。随后,它顺序地读取字符串中的每一个字符,并根据当前状态和读入的字符,按照某个事先约定好的「转移规则」,从当前状态转移到下一个状态;当状态转移完成后,它就读取下一个字符。当字符串全部读取完毕后,如果自动机处于某个「接受状态」,则判定该字符串「被接受」;否则,判定该字符串「被拒绝」。
例子:给定一个字符串str=“111011010010”,通过构建一个有限状态自动机,来判定是否满足偶数个1。
● 有限状态有两个:奇数个1和偶数个1,即:S={EVEN_ONE,ODD_ONE};
● I={“111011010010”}
● 状态转移函数,和当前状态S和输入有关;转移函数如下

在这里插入图片描述

class Solution {
    private static Map<State, Map<Character, State>> transferMap = new HashMap<>();

    static {
        Map<Character, State> evenOneMap = new HashMap<>();
        evenOneMap.put('1', State.ODD_ONE);
        evenOneMap.put('0', State.EVEN_ONE);
        transferMap.put(State.EVEN_ONE, evenOneMap);
        Map<Character, State> oddOneMap = new HashMap<>();
        oddOneMap.put('1', State.EVEN_ONE);
        oddOneMap.put('0', State.ODD_ONE);
        transferMap.put(State.ODD_ONE, oddOneMap);
    }

    //状态
    enum State {
        EVEN_ONE,//偶数个1,可接受状态
        ODD_ONE//奇数个1
    }

    public boolean recognize(String input) {
        if (input == null) {
            return true;
        }
        //初始状态 0个1也是偶数个1
        State currentState = State.EVEN_ONE;
        for (int i = 0; i < input.length(); i++) {
            currentState = transfer(input.charAt(i), currentState);
            //如果存在转移不了状态直接终止
            if (currentState == null) {
                break;
            }
        }
        return currentState == State.EVEN_ONE;
    }

    private State transfer(char currentChar, State currentState) {
        return transferMap.get(currentState).get(currentChar);
    }
}

2 代码实战

https://leetcode.cn/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof/description/

class Solution {
    private static Map<State, Map<CharType, State>> transferMap = new HashMap<>();
    private static Set<State> acceptStateSet=new HashSet<>();
    static {
        //
        Map<CharType, State> initialMap = new HashMap<>();
        initialMap.put(CharType.SPACE, State.INITIAL);
        initialMap.put(CharType.SIGN, State.SIGN);
        initialMap.put(CharType.NUMBER, State.INTEGER);
        initialMap.put(CharType.POINT, State.POINT_WITHOUT_INT);
        transferMap.put(State.INITIAL, initialMap);

        Map<CharType, State> signMap = new HashMap<>();
        signMap.put(CharType.NUMBER, State.INTEGER);
        signMap.put(CharType.POINT, State.POINT_WITHOUT_INT);
        transferMap.put(State.SIGN, signMap);

        Map<CharType, State> integerMap = new HashMap<>();
        integerMap.put(CharType.NUMBER, State.INTEGER);
        integerMap.put(CharType.POINT, State.POINT_HAS_INT);
        integerMap.put(CharType.EXP, State.EXP);
        integerMap.put(CharType.SPACE, State.END);
        transferMap.put(State.INTEGER, integerMap);

        Map<CharType, State> pointHasIntMap = new HashMap<>();
        pointHasIntMap.put(CharType.NUMBER, State.FRACTION);
        pointHasIntMap.put(CharType.EXP, State.EXP);
        pointHasIntMap.put(CharType.SPACE, State.END);
        transferMap.put(State.POINT_HAS_INT, pointHasIntMap);

        Map<CharType, State> pointWithoutIntMap = new HashMap<>();
        pointWithoutIntMap.put(CharType.NUMBER, State.FRACTION);
        transferMap.put(State.POINT_WITHOUT_INT, pointWithoutIntMap);

        Map<CharType, State> fractionMap = new HashMap<>();
        fractionMap.put(CharType.NUMBER, State.FRACTION);
        fractionMap.put(CharType.EXP, State.EXP);
        fractionMap.put(CharType.SPACE, State.END);
        transferMap.put(State.FRACTION, fractionMap);

        Map<CharType, State> expMap = new HashMap<>();
        expMap.put(CharType.NUMBER, State.EXP_NUMBER);
        expMap.put(CharType.SIGN, State.EXP_SIGN);
        transferMap.put(State.EXP, expMap);

        Map<CharType, State> expSignMap = new HashMap<>();
        expSignMap.put(CharType.NUMBER, State.EXP_NUMBER);
        transferMap.put(State.EXP_SIGN, expSignMap);

        Map<CharType, State> expNumberMap = new HashMap<>();
        expNumberMap.put(CharType.NUMBER, State.EXP_NUMBER);
        expNumberMap.put(CharType.SPACE, State.END);
        transferMap.put(State.EXP_NUMBER, expNumberMap);

        Map<CharType, State> endMap = new HashMap<>();
        endMap.put(CharType.SPACE, State.END);
        transferMap.put(State.END, endMap);

        acceptStateSet.add(State.INTEGER);
        acceptStateSet.add(State.END);
        acceptStateSet.add(State.EXP_NUMBER);
        acceptStateSet.add(State.FRACTION);
        acceptStateSet.add(State.POINT_HAS_INT);
    }

    enum State {
        INITIAL, //初始化,
        SIGN,//符号位
        INTEGER,//整数部分--可接受状态
        POINT_HAS_INT,//小数点左侧有整数如:2. --可接受状态
        POINT_WITHOUT_INT,//小数点左侧有无整数如:.3
        FRACTION,//小数部分 ---可接受状态
        EXP,//指数E,e
        EXP_SIGN,//指数符号位
        EXP_NUMBER,//指数后面整数----可接受状态
        END//末尾空格----可接受状态
    }

    enum CharType {
        NUMBER, //数字
        EXP,//指数E或者e
        POINT,//小数点
        SIGN,//符号
        SPACE,//空格
        ILLEGAL//非法
    }

    public boolean isNumber(String input) {
        if (input == null) {
            return true;
        }
        State currentState = State.INITIAL;
        for (int i = 0; i < input.length(); i++) {
            currentState = transfer(input.charAt(i), currentState);
            //如果存在转移不了状态直接终止
            if (currentState == null) {
                break;
            }
        }
        return acceptStateSet.contains(currentState);
    }

    //转移函数
    private State transfer(char currentChar, State currentState) {
        CharType charType = toCharType(currentChar);
        return transferMap.get(currentState).get(charType);
    }

    private CharType toCharType(char currentChar) {
        if (currentChar >= '0' && currentChar <= '9') {
            return CharType.NUMBER;
        } else if (currentChar == 'E' || currentChar == 'e') {
            return CharType.EXP;
        } else if (currentChar == '.') {
            return CharType.POINT;
        } else if (currentChar == ' ') {
            return CharType.SPACE;
        } else if (currentChar == '+' || currentChar == '-') {
            return CharType.SIGN;
        }
        return CharType.ILLEGAL;
    }
}

3 对实际工作的启发

状态机是由事件、状态、动作三大部分组成。三者的关系是:事件触发状态的转移,状态的转移触发后续动作的执行。其中动作不是必须的,也可以只进行状态转移,不进行任何操作。如下图所示,可以受状态机启发对营销活动状态流转进行改造。
在这里插入图片描述
在这里插入图片描述

参考文献
[1] 万门大学,有限状态自动机课程

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

有限状态自动机 的相关文章

  • 删除匿名监听器

    当尝试采用使用匿名或嵌套类实现侦听器的风格时 以便隐藏除侦听之外的其他用途的通知方法 即我不希望任何人能够调用actionPerformed 例如来自java动作监听器 实现与匿名类 https stackoverflow com ques
  • 启动 Java 时使用 -d32 和 -d64

    我阅读了以下摘录JDK 常见问题解答 http www oracle com technetwork java hotspotfaq 138619 html 64bit layering 如何在 32 位和 64 位操作之间进行选择 默认是
  • 外部硬件指纹扫描仪和 Android 设备集成

    我想建立一个android像员工考勤这样的应用程序使用fingerprint scanner 我想知道 是否可以使用外部硬件设备进行指纹识别 扫描 如何将Android应用程序与外部硬件finger集成 打印扫描设备 如何从外部硬件设备获取
  • 将图像作为 JPanel 的背景

    我是 Java 新手 目前正在创建一个带有图形的游戏 我有这个课程从JFrame 在这个班级里 我有很多JPanel需要图像作为背景 据我所知 为了能够在 JPanel 中绘制图像 我需要一个从 JPanel 扩展的单独的类以及该类的pai
  • 是什么使得 java 中的枚举不可实例化?

    我知道一个枚举 enum Year First Second Third Fourth 被转换成 final class Year extends Enum
  • 在 Java 构建过程中更改常量的最佳方法

    我继承了一个在 Tomcat 下运行的 Java 应用程序 servlet 由于历史原因 根据应用程序的部署位置 本质上是品牌问题 代码具有不同的 外观和感觉 选项 有几个常量控制这个品牌过程 它们具有不同的功能 不应压缩为单个常量 即 B
  • 无法解析导航抽屉中片段中的 getSystemService

    我正在尝试实现一个导航抽屉 其中有一个片段中的地图 这是我的代码 这里是fragment map xml
  • Java:计算字符串中字母的出现次数

    我正在尝试编写一个程序来计算字符串中字母的出现次数 例如 如果用户输入 Java 则会显示 j 1 a 2 v 1 但是 我的程序似乎有问题 当我输入 java 这个词时 它显示的是 j 0 a 1 v 0 Scanner myScanne
  • Android 在 ROOM 数据库中插入大量数据

    我有大约 10 个模型 每个模型都有超过 120K 行和 90 列的记录 其中包含双数组值 在 Room 中插入任何模型都需要超过 125 130 秒 任何人都可以建议我需要做什么才能使用一些批量插入技术来保存所有这些 120K 该技术大约
  • MySQL 中电话号码的最佳数据类型是什么?它的 Java 类型映射应该是什么?

    我正在将 MySQL 与 Spring JDBC 模板一起用于我的 Web 应用程序 我需要存储仅包含数字的电话号码 10 我对使用数据类型的数据类型有点困惑 MySQL 中最适合它的数据类型是什么 为此 Bean POJO 类中的 Jav
  • 无法在 Spring boot 中使用 findOne() 方法

    我的项目是关于用户管理器网络的 我是 Spring 和 Java 的新手 这是我的代码 在 UserController 中 RequestMapping value users name method RequestMethod GET
  • 如何使用 apache commons cli 指定多个选项?

    我想要这样的东西 java programName jobs1 C 10 W 20 java programName job2 java programName job3 含内容 Option o1 new Option job2 some
  • 非法监控状态异常

    如何将轮询线程传递给另一个线程进行处理 程序执行在控制器类中 该类具有 main 方法和线程池 主类控制器 public static void main String args throws InterruptedException Ru
  • 如何正确安装mysqlconnecter java?

    上网冲浪后 我意识到我应该在系统环境变量中设置类路径连接器 jar 文件的路径文件我这样做了 并在命令行中输入此命令我有这个 C Users User gt echo classpath D classpath mysql connecto
  • 想要从 beanIO 字段名称标签在 csv 中写入标题

    我想在 csv 文件中写入标题 因为我的文本文件不包含任何标题 所以我想从 beanIO 字段名称标签写入它 我有一个 beanIO 有两个流 一个用于读取 另一个用于写入 这是输入文件 文本输入 txt 1 约翰 露 BA xxx1萨姆
  • 如何在 Spring Boot 中访问 application.properties 文件中定义的值

    我想访问中提供的值application properties e g logging level org springframework web DEBUG logging level org hibernate ERROR loggin
  • 如何在 groovy 中将输出重定向到 stderr?

    我正在寻找一种将 groovy 脚本中的输出重定向到 stderr 的方法 catch Exception e println Want this to go to stderr 就在我的脑海中 你不能做一些自我接线吗 def printE
  • 定时器启动/停止参数

    自从加入这个社区以来 我在技能和进步方面取得了突飞猛进的进步 你们都是一个巨大的帮助 我无法提供一个计时器 该计时器已在启动和停止时实现了某些参数 我要么收到错误消息 局部变量计时器可能尚未初始化 要么没有收到错误消息 但什么也没有发生 也
  • java:验证 GUI 中的所有文本字段是否已完成

    我正在尝试创建一个允许某人设置帐户的 GUI 我想验证按下创建帐户按钮时所有文本字段是否完整 做这个的最好方式是什么 我正在附加我的代码 但我对文本字段是否完整的验证不起作用 参见下面的代码 public class GUIaccounts
  • 在同一项目上使用 Eclipse 和 NetBeans

    Eclipse 是一个非常棒的编辑器 我更喜欢使用它 但是缺少 Eclipse 的 GUI 设计工具 另一方面 NetBeans 非常适合 GUI 设计 在同一项目中使用 NetBeans 进行 GUI 设计和 Eclipse 进行其他所有

随机推荐

  • linux远程访问neo4j

    一 首先确保权限 看看能不能打开防火墙端口 我在搭建好了之后遇到了问题 WebSocket connection failure Due to security constraints in your web browser 尝试了几个方法
  • Linux中的read函数

    2023年7月11日 周二晚上 在 Linux 中 read 函数是一个系统调用 用于从文件描述符 file descriptor 中读取数据 头文件是unistd h 它的原型如下 include
  • 关于嵌入式人工智能?

    关于嵌入式人工智能 虽然学术界目前还没有嵌入式人工智能的确切定义 但随着人工智能的发展 势必会下沉到边缘 终端和嵌入式市场 嵌入式人工智能将会是未来几年AI发展的方向之一 并将伴随一系列的职位和角色涌现 最近很多小伙伴找我 说想要一些嵌入式
  • 基于STM32F103单片机的智能温室大棚RS485通信温湿度监测

    系统功能设计 末尾附文件 STM32单片机智能大棚485上传温湿度光照检测补光 本系统由STM32单片机RS485采集板和STM32单片机RS485显示按键板组成 采集板由STM32F103C8T6单片机 RS485通信模块 光照采集 温湿
  • springboot 一个项目中配置多个redis实例

    在实际的项目中 可能一个项目需要操作多个不同redis的数据 那么我们就需要做相应的配置 以下是基于springboot 首先在我们项目的 application proterties中添加如下配置 有几个就写几个 注意这里的命名 spri
  • 使用ffmpeg 命令分割视频方法

    用法说明 ss 起始时间 i 要分割的是频文件 t 分割时长 格式如下 可以是 t xx 单位 秒 或者 t 01 00 00 时 分 秒 注意 ss 要放在 i 之前 实例 ffmpeg ss 00 00 00 i Video 20210
  • JS实现翻译的多种方案

    JS实现翻译的多种方案 1 language js 库 https languages js org docs 适应于 React Angular 和 Vue2 需要时再学 import Languages from languages j
  • 分库分表实战(7):抽丝剥茧 — 千万级数据之sql优化下篇

    V X ruyuanhadeng获得600 页原创精品文章汇总PDF 前言 上一期 我们讲解了sql优化的一般流程 不管是优化join语句 where语句 聚合函数还是排序操作 核心在于利用索引来优化sql语句 但是 大家以为我们为字段创建
  • sonar报java.io.StreamCorruptedException: invalid internal transport message format, got (48,54,54,50)

    昨天运行sonar还好好的 今天运行就自动退出了 sonar log日志文件如下 gt Wrapper Started as Console Launching a JVM Wrapper Version 3 2 3 http wrappe
  • 蓝桥杯题库 历届试题部分(C++、Java)代码实现(31-45)

    文章目录 五 历届试题 PREV 31 小朋友排队 PREV 32 分糖果 PREV 33 兰顿蚂蚁 PREV 34 矩阵翻硬币 PREV 35 正则问题 PREV 36 包子凑数 PREV 37 分巧克力 PREV 38 油漆面积 PRE
  • LDO的六大重要参数,你务必一一牢记

    在电子设计中 我们经常需要用到不同的直流电压给不同器件供电 其中用的最广泛的就是通过LDO稳压芯片来实现得到不同的直流电压输出 因为成本低 性能好 且使用起来也很简单 让LDO稳压芯片用的也越来越多 几乎每款电子产品里都有其身影 说它好用
  • 【STM32】认识库函数引脚GPIO开启时钟,需要初始化的结构体GPIOMode_TypeDef

    GPIO Mode AIN 0x0 GPIO Mode IN FLOATING 0x04 GPIO Mode IPD 0x28 GPIO Mode IPU 0x48 GPIO Mode Out OD 0x14 GPIO Mode Out P
  • html安卓关闭输入面板,tabletpc输入面板关闭不了怎么办(tablet pc输入面板关闭方法)...

    平时在我们用到一些电脑中的小工具的时候可以快速的打开 大多数的情况下只要想关闭打开的面板 只需要关闭右上角的红色小叉就可以快速的关闭 tablet pc 输入面板这样关闭不了怎么解决 我们在使用这个小工具的时候通常会在任务栏中点击右键 在菜
  • Android 获取项目证书指纹MD5、SHA1、SHA256步骤详解

    前些天发现了一个蛮有意思的人工智能学习网站 8个字形容一下 通俗易懂 风趣幽默 感觉非常有意思 忍不住分享一下给大家 点击跳转到教程 第一步 首先找到Android studio依赖的本地JDK路径 第二步 找到路径输入cmd 第三步 输入
  • Restful风格详解

    Restful风格的描述与解释 转载 https www cnblogs com letsdaydayup p 14441123 html 文章目录 Restful风格的描述与解释 一 什么是Restful风格 二 Restful的特点 实
  • OpenHarmony 3D显示支持

    前言 OpenHarmony系统是一个非常先进 现代化设计理念的新系统其系统架构图如下 一 图形子系统架构图 图形子系统是最复杂的一个 标准版这里2D的部分 foundation graphic graphic 2d rosen modul
  • 流计算处理系统入门

    时间可以划分成两种 处理时间 数据抵达流计算系统开始进行处理的时间 数据被处理的时间 事件时间 被检测系统获得数据的时间 一般用时间戳的方式携带在数据中 处理时间 晚于 数据事件时间 流计算框架 Hadoop 批处理框架 采集的数据全存入H
  • xssgame第十一关至第十四关

    第十一关 首先查看源码 我们获得到新的t ref参数 这个参数有点像http的请求头的refer值 我们用bp抓包尝试在请求头refer输入值查看结果 打开bp 添加一条 Referer type text nm use ver alert
  • 目标检测中将已有的.xml数据集转换成.txt数据集(附代码,归一化后供YOLO格式使用)

    目标检测中将已有的 xml数据集转换成 txt数据集 附代码 归一化后供YOLO格式使用 1 新建项目 我新建了data目录并新建Annotations images ImageSets JPEGImages labels 五个文件夹 其中
  • 有限状态自动机

    1 什么是有限状态自动机 1 1什么是计算 维基百科定义 计算 英语 Calculation 是一种将 单一或多个的输入值 转换为 单一或多个的结果 的一种思考过程 可以简单理解为给出一个问题得到一个答案的过程 如下图所示日常生活比较常见计