有限状态机详解(转载)

article/2025/9/29 16:25:26

以前总觉得有限状态机和无限状态机非常的难理解,原来也就是自己一直没有一个直观的认识,今天看到一篇博客,总算对有限状态机入门了。一看就懂。

转载地址:http://blog.csdn.net/zqixiao_09/article/details/50239337

我们知道,一般编写程序时都要画出流程图,按照流程图结构来编程,如果编写一个比较繁琐,容易思维混乱的程序时,我们可以利用有限状态机模型画出一个状态转移图,这样便可以利用画出的逻辑图来编写程序,简洁且不易出错。
那什么是有限状态机是什么意思呢?百度百科上这样解释:
有限状态机,(英语:Finite-state machine, FSM),又称有限状态自动机,简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。
这里写图片描述

常见的计算机就是使用有限状态机作为计算模型的:对于内存的不同状态,CPU通过读取内存值进行计算,更新内存中的状态。CPU还通过消息总线接受外部输入设备(如键盘、鼠标)的指令,计算后更改内存中的状态,计算结果输出到外部显示设备(如显示器),以及持久化存储在硬盘。
电脑游戏设计中也经常使用有限状态机模型。以水果忍者游戏为例,游戏中水果的状态是有限状态,其运行轨迹是由模拟物理运动规律的计算公式运算而成的,一个香蕉抛起来后会按照抛物线运行,其每一帧位置变化都是一个状态的改变,状态改变通过计算公式来决定。当然作为游戏不会仅仅这么简单,如果这么简单就是动画了,游戏还有复杂的人机交互事件,比如用手在屏幕上“切”了水果,水果感知到这个事件后,会按照程序逻辑进入爆炸状态。

简单知道其定义是没有用的,在C编程中我们改如何应用呢?

例题1:去除一个字符串中连续的空格,即 H__el___lo 变成 H_el_lo;

我们拿到这道题时,可能会想到用getchar()依次取字符,当遇到空格时,继续下一个字符是否为空格,如果是则删除,如果不是则继续;那么问题来了,如果空格后面还有空格呢?如果还有很多空格呢?如果还有其他要求呢?这样很容易造成思维混乱,所以这时我们可以用到有限状态机模型,好像这样说很模糊啊,该怎么使用呢?利用这种方式,最后的就是利用好flag,即标识符;这样吧,我们来画一下这个模型:
这里写图片描述
这样看好像有点抽象,我来解释一下:
状态0 (flag = 1)若当前字符是空格,输出并跳转到状态1(flag = 1),如果是非空格,则打印字符;
状态1 (flag = 1) 若当前字符为非空格,则输出并跳转到状态0,若是空格,则不打印;
下面几个例题我尽量写得清楚;

我们按照这种逻辑来写程序,看看是不是比较方便,代码如下:

#include <stdio.h>  int main(int argc, char *argv[])  
{  char flag = 0;  int ch;  while((ch = getchar()) != EOF)  {  switch(flag)  {  case 0:  if(ch == ' ')  flag = 1;  putchar(ch);  break;  case 1:  if(ch == ' ')  continue;  flag = 0;  putchar(ch);  break;  default:  break;  }  }  return 0;  
}  

程序执行结果如下:

[cpp] view plain copy
fs@ubuntu:~/qiang/char1$ gcc -o test test.c   
fs@ubuntu:~/qiang/char1$ ./test  
H  el   lo  
H el lo  

效果很明显;

上面的例题还算简单吧,好像不用这个模型也可以是吧,那好,我们再来一题

例题2:除连续的空格但字符串中的连续空格不变,比如H_ _el__"wor___ld"___lo;
大家看看,如果直接写程序是不是很烦,一会就乱掉了,那我们还用这个模型来编写,还是先画图:
这里写图片描述

#include <stdio.h>  int main(int argc, char *argv[])  
{  char flag = 0;  int ch;  while((ch = getchar()) != EOF){  switch(flag){  case 0:  if(ch == ' ')  flag = 1;  if(ch == '"')  flag = 2;  putchar(ch);  break;  case 1:  if(ch != ' '){  flag = 0;  if(ch == '"')  flag = 2;  putchar(ch);  }  break;  case 2:  if(ch == '"')  flag = 0;  if(ch == '\"')  ch = '"';  putchar(ch);  break;  default:  printf("error!\n");  break;  }  }  return 0;  
}  

执行结果如下:

[cpp] view plain copy
fs@ubuntu:~/qiang/char1$ ./char3  
H  el  "wor   ld"   lo  
H el "wor   ld" lo  

来个实际点的问题:
例题3::除单行注释
示例程序:

/*******this is program*****/
#include <stdio.h>
int main()  
{  printf("Hello world!\n");//Hello world!  
}  

将这段程序中的单行注释去掉,继续画图:

这里写图片描述
编写程序如下:

#include <stdio.h>  int main(void)  
{  char flag = 0;  char ch;  while((ch = getchar()) != EOF)  {  switch(flag)  {  case 0:  if(ch == '/')  flag = 1;  else  putchar(ch);  break;  case 1:  if(ch == '/'){  flag = 2;  }  else{  putchar('/');  putchar(ch);  }  break;  case 2:  if(ch == '\n')  {  flag = 0;  putchar(ch);  }  break;  default:  break;  }  }  
}  

执行命令:

fs@ubuntu:~/qiang/char1$ ./quzhushi1 < test.c >result.c  

注意命令中用到的重定向,将test.c文件重定向到quzhushi1 中,输出结果重定向到 result.c中

可查看result.c中:

/*******this is program*****/
#include <stdio.h>
int main()  
{  printf("Hello world!\n");//Hello world!  
}  

单行注释被删除。

例题4:去除单行注释和多行注释
还是这个测试程序:

/*******this is program*****/
#include <stdio.h>
int main()  
{  printf("Hello world!\n");//Hello world!  
}  

好吧,继续画图,图上比较抽象,大家可以自己思考一下
这次比较复杂,要有5个标识符
这里写图片描述

测试代码如下:

#include <stdio.h>  int main()  
{  char ch;  int flag = 0;  while((ch = getchar()) != EOF)  {  switch(flag)  {  case 0:  if(ch == '/')  flag = 1;  else  putchar(ch);  break;  case 1:  if(ch == '/')  flag = 2;  else if(ch == '*')  flag = 3;  else  {  flag = 0;  putchar('/');  putchar(ch);  }  break;  case 2:  if(ch == '\n')  {  putchar(ch);  flag = 0;  }  break;  case 3:  if(ch == '*')  flag = 4;  break;  case 4:  if(ch == '/')  flag = 0;  else  flag = 3;  break;  }  }  
}  

执行命令:

fs@ubuntu:~/qiang/char1$ ./quzhushi < test.c >result.c  

执行结果:

/*******this is program*****/
#include <stdio.h>
int main()  
{  printf("Hello world!\n");//Hello world!  
} 

大家可以比较画的图与所写程序,这种方法可以使我们编写程序时有个很好的思路!


http://chatgpt.dhexx.cn/article/vfhKErHb.shtml

相关文章

状态机

有限状态机&#xff08;Finite State Machine或者Finite State Automata)是软件领域中一种重要的工具&#xff0c;很多东西的模型实际上就是有限状态机。最近看了一些游戏编程AI的材料&#xff0c;感觉游戏中的AI&#xff0c;第一要说的就是有限状态机来实现精灵的AI&#xff0…

状态机的深入理解

目录 1.什么是状态机 2. 生活中的状态机 3. 工程中的应用 4. 发散思考 1.什么是状态机 ■1.1 有向图 有向图是指由定点和边构成的集合&#xff0c;我们常用G&#xff08;E, V&#xff09;来表示一个有向图&#xff0c;其中定点之间由有向边进行连接就构成了有向图。有向图…

有限状态机

文章目录 有限状态机状态机的表示状态转移图二维表 实现穷举法查表法状态模式 总结 有限状态机 有限状态机(Finite State Machine) 缩写为 FSM。以下简称为状态机。 状态机有 3 个组成部分&#xff1a;状态、事件、动作。 状态&#xff1a;所有可能存在的状态。包括当前状态和…

什么是状态机?

前言 状态机在实际工作开发中应用非常广泛&#xff0c;在刚进入公司的时候&#xff0c;根据公司产品做流程图的时候&#xff0c;发现自己经常会漏了这样或那样的状态&#xff0c;导致整体流程会有问题&#xff0c;后来知道了状态机这样的东西&#xff0c;发现用这幅图就可以很…

什么是状态机(Finite-state machine)?

有限状态机 有限状态机(FSM)1、 什么是“状态”2、什么是状态机&#xff1f;3、状态机图怎么画&#xff1f;参考 有限状态机(FSM) 1、 什么是“状态” 先来解释什么是“状态”&#xff08; State &#xff09;。现实事物是有不同状态的&#xff0c;例如一个自动门&#xff0c…

什么是状态机?用C语言实现进程5状态模型

前言 状态机在实际工作开发中应用非常广泛&#xff0c;在刚进入公司的时候&#xff0c;根据公司产品做流程图的时候&#xff0c;发现自己经常会漏了这样或那样的状态&#xff0c;导致整体流程会有问题&#xff0c;后来知道了状态机这样的东西&#xff0c;发现用这幅图就可以很…

状态机(state machine)

一、状态机分类 Mealy状态机:输出取决于输入和当前状态 状态寄存器:由一组触发器组成,用来记忆状态机当前所处的状态,状态的改变只发生在时钟的跳变沿。状态寄存器由一组触发器组成,用来记忆状态机当前所处的状态,状态的改变只发生在时钟的跳变沿。 状态是否改变、如何…

状态机(有限状态自动机 FSM)介绍以及常用状态机种类对比

目录 状态机概念 : 为什么需要状态机: 使用场景 状态机四要素: 常见类型状态机: Squirrel State Machine Spring Statemachine 状态机概念 : 概念 : 状态机是有限状态自动机&#xff08;英语&#xff1a;finite-state machine&#xff0c;缩写&#xff1a;FSM&#xff…

STM32状态机编程----什么是状态机?

万事万物都有其状态 什么是状态 状态是人或事物表现出来的形态。是指现实&#xff08;或虚拟&#xff09;事物处于生成、生存、发展、消亡时期或各转化临界点时的形态或事物态势。 通过上面那句话&#xff0c;我们知道了状态就是一个对象在不同情况下对应的各种形态 做产品的…

什么是状态机?一篇文章就够了

1 概述 状态机[1]一般指有限状态机&#xff08;英语&#xff1a;finite-state machine&#xff0c;缩写&#xff1a;FSM&#xff09;又称有限状态自动机&#xff08;英语&#xff1a;finite-state automaton&#xff0c;缩写&#xff1a;FSA&#xff09;&#xff0c;是表示有限…

C语言_有限状态机(FSM)

C语言_有限状态机&#xff08;Finite State Machine&#xff09; 基本介绍 许多小型或复杂的应用程序都使用有限状态机 (FSM)&#xff0c;C 语言中的有限状态机是嵌入式系统的流行设计模式之一&#xff0c;有限状态机使开发变得容易和顺利。 有很多设备使用事件基态&#xf…

Unity字体展示下载

Unity字体种类展示 这是字体包里面的图片,是不是很多种字体. 下载链接: https://download.csdn.net/download/qq_42603590/12001130 这是下载字体包的地方,很便宜.没有积分的可以留言,我发给你 有时候可能回复的不是很快(抱拳了) 喜欢的话点个赞,关注一下再走吧,谢谢

Unity 之 官网下载地址,方便各个版本的 Unity 安装包下载

Unity 之 官网下载地址&#xff0c;方便各个版本的 Unity 安装包下载 目录 Unity 之 官网下载地址&#xff0c;方便各个版本的 Unity 安装包下载 一、简单介绍 二、各个版本下载入口网址 一、简单介绍 在 Unity 的下载地址现在不是很好找&#xff0c;这里保存一下 Unity 各…

Unity入门之路0-Unity下载安装以及版本选择

文章目录 下载链接Unity Hub和Unity的关系UnityHub下载(Win)两者比较 Unity版本选择许可证问题 下载链接 一定不要百度或者去垃圾网站下载盗版网站 &#xff0c;Unity是正版免费的&#xff0c;官方很关注使用者的感受&#xff0c;所以下载官网的就没问题。 https://unity.cn/re…

UnityHub下载缓存位置

一、下载Unity各版本的编辑器 C:\Users\XXX\AppData\Local\Temp\unityhub-xxx-xxx-xxx-xxx 我电脑是 C:\Users\Administrator\AppData\Local\Temp\unityhub-xxxx-xxxx 如果你不需要备份安装包&#xff0c;那么这个缓存的文件夹&#xff0c;就与你无关了&#xff0c;因为安装完…

使用UnityHub下载任意版本Unity

目录 方法一 使用链接方法二 官网下载(适用于2018.4.23及以上版本) unityHub上只能下载官方指定的版本,很多其他版本不能下载,下面介绍的是在unityHub下载任意版本的方法 方法一 使用链接 举例: 2019.2.11f1版本的unity----> unityhub://2019.2.11f1/5f859a4cfee5 格式 unit…

Unity给游戏对象贴图、从官网下载资源、导入导出

1、新建项目、在项目场景中创建几何对象并修改参数 在层级“”中创建一个立方体&#xff08;3D对象&#xff09;&#xff0c;同理也创建一个球体 创建好的立方体会显示在场景视图中 &#xff08;从场景视图或层级视图中&#xff09;选中几何体&#xff0c;选择场景视图中竖排工…

unity下载网页所有图片

用unity的c#脚本批量下载网页上的所有图片 1、将网页的html保存到本地 在网页上鼠标右击另存为如下图所示 保存html文件 2、通过截取<img“”>获取图片存储的地址 经过两个步骤之后就可以开始着手敲代码了 代码 html下载的本地地址和要保存的图片地址 //保存在本地ht…

Unity下载方法(超详细)

一、进入官网&#xff0c;点击[下载Unity]&#xff0c;点击右上角的小人头像&#xff0c;点击[创建Unity ID](创建ID的方法你点进去按照它要求你的一步一步做就行啦)。 二、创建完Unity ID并登录(或已有Unity ID并登录)后&#xff0c;下拉网页&#xff0c;点击[下载Unity Hub]&…

Unity 改变下载资源商店中资源默认路径的方法

Unity 改变下载资源商店中资源默认路径的方法 Unity资源商店中免费资源可以被我们很好的使用&#xff0c;尤其对于暂时还不会自己设计资源的创作者。但是&#xff0c;unity默认是将资源商店的下载路径设置在了C:\Users\操作系统当前用户\AppData\Roaming\Unity\Asset Store-5.x…