前一篇文章介绍了什么是FSA以及用FSA识别字符串的基本原理。这篇文章就是基于状态转移表,用一个具体的例子讲一下一个简单的FSA如何用Python代码实现。
前一篇介绍FSA的文章:
链接: link.
回顾一下通过状态转移表理解FSA识别字符串的工作过程,一个状态转移表如下图:
它识别一个字符串的工作过程是:定义初始状态为0,接收状态为4,从初始状态0开始,如果输入b,则进入1状态,如果输入a或!则拒绝,识别失败,就这样一直到接收状态4,则整个字符串被接收,识别成功。
下图是利用状态转移表,用FSA识别字符串的算法:
这是一个确定性的FSA,所谓确定性的FSA,就是对于任何的输入,算法都有对应的下一步。进一步看一下上图的算法,该算法有三个结束状态:
①识别到最后一个字符,该字符会被接收,则返回True。
②识别到最后一个字符,该字符不被接收。返回False。
③还没识别到最后一个字符,该字符不被接收,返回False。
下面通过一个简单的例子,用python实现一下FSA。
题目是这样的:编写一个FSA,参照上图算法流程,要求仅能接收大写字母和数字。
这个题目用不用FSA很简单就可以实现,但这里我们要求用FSA来实现,其原理可以推广到用FSA识别更复杂的字符串。
分析一下解题步骤:
(1)确定待接收的字符:大写字母,数字。
(2)根据待接收字母确定状态:①初始状态0:指定的初始状态。②状态1:接收到字母或数字。
(3)用有向图分析状态转移的过程:
题目很简单,除了初始状态就一个状态,一直再状态1循环,知道接收完所有字符或者某个字符被拒绝。
下面看下具体的代码:
def is_digigit_upper(tape:str):
"""
function:输入一个字符串,如果它只含大写字母和数字,返回True,否则返回False
parameters:
tape:要判断的tape
date:2020/9/19
author:IT'S 2AM
return:True,false
"""
#给出transition_table
transition_table = [{'upper':1,'digit':1}, #初始状态
{'upper':1,'digit':1}] #状态1
current_state = 0;
s = 0 #记录遍历tape的第几个元素
for i in tape:
if i.isdigit(): t = 'digit'
elif i.isupper(): t = 'upper'
else: t = 'other'
if s == len(tape)-1:
if t == 'digit' or 'upper':
return True#情况一:读到tape最后一个元素,该元素依然符合要求,返回True
else:
return False#情况二:读到tape最后一个元素,该元素不符合要求,返回False
elif t == 'other':
return False#情况三:未到tape最后一个元素,该元素不符合要求,返回False
else:
current_state = transition_table[current_state][t]
s = s+1
这里用了一个list来表示状态转移表,一共两个状态,初始状态和状态1。用t来表示接收到的字符属于哪一类,大写字母和数字被接收,其他情况被拒绝。
验证:
test_1 ='ABC'
print(is_digigit_upper(test_1))
结果:True
参考文章:
链接: link.