启发自 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>
本文介绍了一种基于有限状态自动机(FSM)的计算模型,并通过一个具体的示例来展示如何使用FSM抑制比特流中的新1。讨论了FSM的数据结构及其实现方式,并提供了一个JavaScript实现的例子。
146

被折叠的 条评论
为什么被折叠?



