启发自 more programming pearls 2
有限状态自动机(FSM)是计算的一种优雅的数学模型和有用的实践工具,它在程序设计语言的语法分析,通信协议以及简单的硬件设备等许多应用领域都有广泛的用途。
例子:抑制比特流中的所有新出现的1:
input:011010111
output:001000011
紧跟在0后面的1变成0,输入流中的其他比特流位不改变。
自动状态机:
对应的两状态自动机在其状态中对最后一个输入比特进行编码:liz 表示 last input zero ,lio表示 last input one
指向liz的横向箭头表示这是初始状态。从liz到lio的弧线表示,如果自动机当前处于liz且输入是一个1,则输出一个0并进入到状态里欧。
数据结构:
执行fsm程序需要两个数据结构:
如果fsm包含弧线:
则下列等式成立
trans[state1,insym] == state2
out[state1,insym] == outsym
trans 表示状态转换,out表示输出符号。
则我们可得到trans,out后即可进行自动机的运转。
程序例子:
<script type="text/javascript"> /* input:011010111 output:001000011 */ var Fsm = function(transMap){ this.initTrans(transMap); }; /* 载入有限状态机 */ Fsm.prototype.initTrans = function(transMap){ //当前状态,当前值 => 下一个值 this.out={}; //当前状态,当前值 => 下一个状态 this.trans={}; for(var i=0,l=transMap.length;i<l;i++) { var tranMap=transMap[i]; //trick this.trans[tranMap['from']]=this.trans[tranMap['from']]||{}; this.out[tranMap['from']]=this.out[tranMap['from']]||{}; this.trans[tranMap['from']][tranMap['fromValue']]=tranMap['to']; this.out[tranMap['from']][tranMap['fromValue']]=tranMap['toValue']; } }; /* 根据已有有限状态机和已有序列得出结果序列 */ Fsm.prototype.run = function(params){ var currentState=params.start; var sequence=params.sequence; var result=[]; for(var i=0,l=sequence.length;i<l;i++) { var currentValue=sequence[i]; result.push(this.out[currentState][currentValue]); currentState=this.trans[currentState][currentValue]; if(!currentState){alert("transMap 出错了 !");return[]} } return result; }; (function main() { var metaState=[ //当前状态为 from,当前值为 fromValue //转换后状态为 to,值为 toValue { from:'liz', fromValue:0, to:'liz', toValue:0 }, { from:'liz', fromValue:1, to:'lio', toValue:0 }, { from:'lio', fromValue:0, to:'liz', toValue:0 }, { from:'lio', fromValue:1, to:'lio', toValue:1 } ]; var fsm=new Fsm(metaState); var result=fsm.run({ start:'liz', sequence:[0,1,1,0,1,0,1,1,1] }); alert(result); })(); </script>