《编程珠玑(续)(修订版)》—第2章2.2节有穷状态机模拟器

2.2 有穷状态机模拟器
有穷状态机(FSM)是计算的一种优雅的数学模型和有用的实践工具,它在程序设计语言的词法分析、通信协议以及简单硬件设备等许多应用领域都有广泛的用途。Wulf、Shaw、Hilfinger和Flon在他们合著的Fundamental Structures of Computer Science③一书(Addison-Wesley出版社1981年出版)的1.1节讨论了这一主题。

作为例子,他们考虑这样一个简单的任务——“抑制”比特流中所有新出现的1:

Input:    011010111
Output:    001000011

紧跟在0后面的1被改成0,输入流中的所有其他比特位不变。

下面的两状态自动机在其状态中对最后一个输入比特进行编码:“LIZ”表示“Last Input Zero”,而“LIO”表示“Last Input One”。

指向LIZ的横向箭头表明这是初始状态。从LIZ到LIO的弧线的意思是,如果自动机当前处于状态LIZ且输入是一个1,则输出一个0并进入状态LIO。
执行FSM的程序使用两个主要数据结构。如果FSM包含弧线

那么下面的等式成立:

trans[State1, InSym]   == State2
out[State1, InSym]   == OutSym

名字trans表示状态转换,out表示输出符号。

上面描述的自动机和输入编码如下:

LIZ  0  LIZ  0
LIZ  1  LIO  0
LIO  0  LIZ  0
LIO  1  LIO  1
start    LIZ
0
1
1
0
...

前4行表示FSM中的4条边。第一行说,如果自动机当前状态为LIZ且输入为0,那么下一个状态是LIZ并输出0。第五行确定初始状态,之后的行是输入数据。

下面的程序按上面描述的形式执行FSM。

run == 1 { print out[s, $1]; s = trans[s, $1]  }
run == 0 { if ($1 == "start") { run = 1; s = $2 }
      else { trans[$1, $2] = $3; out[$1, $2] = $4 }
     }

该程序有两个主要的模式。起初,变量run值为零。在这个模式下,将自动机的转换添加到数组trans和out中。当输入的某一行的第一个字段是字符串"start"时,程序将相应的初始状态存放到s中,然后切换到运行模式。然后每步的执行都将产生输出并改变状态,每步转换后的状态可以看成是当前输入($1)和当前状态(s)的函数。

这个微型的程序有很多缺点。例如,对于未定义的转换,它做出的反应将是灾难性的。事实上,这个程序顶多适合个人使用。另一方面,它为创建更健壮的程序提供了便利的基础,见习题2。

时间: 2024-09-21 16:32:01

《编程珠玑(续)(修订版)》—第2章2.2节有穷状态机模拟器的相关文章

《编程珠玑(续)(修订版)》目录—导读

内容提要 编程珠玑(续)(修订版) 本书是计算机科学方面的经典名著<编程珠玑>的姊妹篇,讲述了对于程序员有共性的知识.本书延续了<编程珠玑>的特色,通过一些精心设计的有趣而又颇具指导意义的程序,对实用程序设计技巧及基本设计原则进行透彻而睿智的描述,为复杂的编程问题提供清晰而完备的解决思路.书中涵盖了程序员操纵程序的技术.程序员取舍的技巧.输入和输出设计以及算法示例,这些内容结合成一个有机的整体,如一串串珠玑展示给程序员.本书对各个层次的程序员都具有很高的阅读价值. 版权声明 编程珠

编程珠玑--粗略估算

粗略估算是<编程珠玑>中第七章提到的内容.   这篇文章将"粗略估算"看做是一项工程技术,是程序员必备的一项技能之一. 本人非常同意这个观点.粗略估算是一种把复杂的事情简单化的能力.我们对某个算法的时间复杂度和空间复杂度的估算就是基于这种估算的能力.如果你能较为准确的估算出一个程序的输出结果,如果你能准确估算出这个程序的运行时间,如果你能准确估算出这个项目的开发时间--如果你能拥有这样的能力,该有多么美好啊.所以难怪乎像微软.Google这样的大公司老喜欢出"请计

《编程珠玑(续)(修订版)》—第1章1.1节计算素数

第1章 性能监视工具 编程珠玑(续)(修订版) 听诊器是一种简单工具,却给医生的工作带来了革命:它让内科医生能有效地监控病人的身体.性能监视工具(profiler)对程序起着同样的作用. 你现在用什么工具来研究程序?复杂的分析系统很多,既有交互式调试器,又有程序动画系统.正如CT扫描仪永远代替不了听诊器一样,复杂的软件也永远代替不了程序员用来监控程序的最简单工具--性能监视工具,我们用它了解程序各部分的执行频率. 本章先用两种性能监视工具来加速一个小程序(记住真正的目的是说明性能监视工具).后续

《编程珠玑(续)(修订版)》—第2章2.1节Awk中的关联数组

第2章 关联数组编程珠玑(续)(修订版)人类学家说,语言深刻地影响了世界观.一般把这个观察结果称为"Whorf假说"① ,也经常把它总结为"语言塑造了人的思想". 跟大多数程序员一样,我使用的Algol系列的语言塑造了我的计算思维.对于像我这样的程序员来说,PL/1.C和Pascal看起来都很相似,我们不难把这样的代码翻译成COBOL或Fortran的代码.用这些语言能轻易地表达我们旧的.习以为常的思维模式. 另外一些语言则挑战了我们对于计算的看法.我们感到惊奇的是

《编程珠玑(续)(修订版)》—第2章2.4节原理

2.4 原理Awk可以使程序员事半功倍.我们目前看到的多数程序如果使用传统的语言编写,代码量恐怕会多出一个数量级.规模的减小归功于Awk的几个特性:输入行之上的隐式循环.自动分隔成字段.变量的初始化和转换,以及关联数组. 关联数组是Awk将字符串和数值这样的基本数据类型结合起来的唯一机制,别无他法.幸而关联数组可以很自然地表示许多数据结构. 数组.一维.多维和稀疏数组实现起来都很容易.顺序结构.队列和栈是由关联数组加一个或两个索引产生的.符号表.符号表提供了从名字到值的一个映射:symtab[n

《编程珠玑(第2版•修订版)》—第1章1.1节一次友好的对话

第一部分 基础 编程珠玑(第2版•修订版) 这一部分的5章回顾程序设计的基础知识.第1章介绍一个问题的历史,我们把仔细的问题定义和直接的程序设计技术结合起来,得到优美的解决方案.这一章揭示了本书的中心思想:对实例研究的深入思考不仅很有趣,而且可以获得实际的益处. 第2章讨论3个问题,其中重点强调了如何由算法的融会贯通获得简单而高效的代码.第3章总结数据结构在软件设计中所起到的关键作用. 第4章介绍一个编写正确代码的工具--程序验证.在第9章.第11章和第14章中生成复杂(且快速)的函数时,大量使

《编程珠玑(第2版•修订版)》—第2章2.1节三个问题

第2章 啊哈!算法 编程珠玑(第2版•修订版) 研究算法给实际编程的程序员带来许多好处.算法课教给学生完成重要任务的方法和解决新问题的技术.在后续的章节中将会看到,先进的算法工具有时候对软件系统影响很大--减少开发时间,同时使执行速度更快. 算法与其他那些深奥的思想一样重要,但在更一般的编程层面上具有更重要的影响.在<啊哈!灵机一动>一书中(本章的标题就借鉴了它),Martin Gardner①描述了深得我心的一个思想:"看起来很困难的问题也可以有一个简单的.意想不到的答案.&quo

《编程珠玑(第2版•修订版)》目录—导读

作者简介编程珠玑(第2版•修订版)Jon Bentley 世界著名计算机科学家,被誉为影响算法发展的十位大师之一.他先后任职于卡内基-梅隆大学(1976~1982).贝尔实验室(1982~2001)和Avaya实验室(2001年至今).在卡内基-梅隆大学担任教授期间,他培养了包括Tcl语言设计者John Ousterhout.Java语言设计者James Gosling.<算法导论>作者之一Charles Leiserson在内的许多计算机科学大家.2004年荣获Dr. Dobb's程序设计卓

编程珠玑--旋转算法

旋转算法出自<编程珠玑>第二章题目.   <编程珠玑>一书对算法是极度推崇,这点意识在我们看书的时候每每都有被灌输.使用一种好的算法往往能使得程序更加漂亮,也很能带给我们程序员某种满足感.   题目:将一个n元一维数组a[n]左移i个位置.例如,当n=8,i=3时,数组abcdefgh旋转为defghabc.请设计一个算法完成这个任务.   1. 块交换法: 分析:将n元一维数组a[n]分解为两块,将第一块存储在临时数组中,将第二块前移i个单位,再将临时数组加入到第二块后面.