编译原理—— 有穷自动机(DFA)识别
实验目的
- 熟练掌握有穷状态机的结构性质,并且能够推导出有限状态机能够识别的字符串格式
实验内容
-
编写程序实现有穷状态机
-
判断该有穷状态机所实现的字符串检测格式
算法描述及实验步骤
-
输入任意字符串
-
初始化状态。
-
遍历输入的字符串,对该状态做相应的判断(以该有穷状态自动机为例)
-
倘若该状态为0(初始状态),则进一步判断当前遍历到的字符,假若为a,则修改当前状态为1,假若为b则修改当前状态为2。
-
倘若该状态为1,则进一步判断当前遍历到的字符,假若为a,则修改当前状态为1,假若为b则修改当前状态为3。
-
倘若该状态为2,则进一步判断当前遍历到的字符,假若为a,则修改当前状态为1,假若为b则修改当前状态为2。
-
倘若该状态为3,则进一步判断当前遍历到的字符,假若为a,则修改当前状态为1,假若为b则修改当前状态为1。
-
倘若该状态为4,则进一步判断当前遍历到的字符,假若为a,则修改当前状态为1,假若为b则修改当前状态为2。
-
-
假如,遍历的过程中,任意一步出现非a或b的字符串,则视为检测失败
-
假如,遍历结束之后,状态为终止状态,则视为该字符串检测成功,否则视为检测失败
调试过程及运行结果
-
分别测试两个串 abb 以及 aagabb ,对程序进行检测
-
abb符合格式要求,接受
- aagabb不符合格式要求,拒绝
总结
-
通过程序得到结论,该有限状态机所检测的字符串为,任意由ab组成的并且以abb结尾的字符串
-
该程序是通过switch语句分别对不同的状态,以及不同的字符识别从而实现状态得到相应的更改,但是这样的做法并不具有延展性,只针对该状态机,倘若,采用二维数组的形式,或者哈希表的形式存储相应的状态转化内容,会使得程序具有更好的延展性
程序源代码
#include <iostream>
#include <cstring>
using namespace std;
bool DFA(string s){
int state=0;
for(int i=0;i<s.size();i++){
//cout<<state<<" "<<s[i]<<endl;
switch(state){
case 0:switch(s[i]){
case 'a':state=1;break;
case 'b':state=2;break;
default :return false;
};break;
case 1:switch(s[i]){
case 'a':state=1;break;
case 'b':state=3;break;
default :return false;
};break;
case 2:switch(s[i]){
case 'a':state=1;break;
case 'b':state=2;break;
default :return false;
};break;
case 3:switch(s[i]){
case 'a':state=1;break;
case 'b':state=4;break;
default :return false;
};break;
case 4:switch(s[i]){
case 'a':state=1;break;
case 'b':state=2;break;
default :return false;
};break;
default :return false;
}
}
if(state==4)return true;
else return false;
}
int main()
{
string s;
cin>>s;
if(DFA(s)){cout<<"Accept"<<endl;}
else {cout<<"Error"<<endl;}
return 0;
}