编译原理中有穷自动机的c++实现

       有穷自动机,也称有限自动机,作为一种识别装置,能够准确的识别正规集,即识别正规文法所定义的语言和正规式所表示的集合。引入有穷自动机理论,正是为词法分析程序的自动构造寻找特殊的方法和工具。

       有穷自动机分为两类:确定的有穷自动机(Deterministic Finite Automata,DFA)和不确定的有穷自动机(Nodeterminister Finite Automata,NFA).

           首先来说DFA。

           一个确定的有穷自动机M是一个五元组:

  •                                

(原谅我打不出这些字母,然后我就放了个图。ps:和书上字母不一样,不过意思差不多。)

具体的例子:

   


用矩阵表示DFA如下:



最开始的时候我写了一个实现最繁琐的小程序,就是这个

#include <iostream>
using namespace std;
class DFA
{
private:
	char state;
public:
	void initialize/*初始化*/(void){
			state='S';
	}
	void transition/*转换*/(char);
	bool in_terminal_state(void){/*终端*/
		if(state=='Q')
			return true;
		else 
			return false;
	}
bool in_fail_state(void){
	if(state=='F')
		return true;
	else
		return false;
}
DFA(void){
	state='S';
}
};
void DFA::transition(char input){/*转换*/
	switch(state){
	case 'S':
		switch(input){
			case 'a':state='U';break;
			case 'b':state='V';break;
            default:break;
			}
			break;
	case 'U':
		switch(input){
		case 'a':state='Q';break;
		case 'b':state='V';break;
        default:break;
		}
		break;
	case 'V':
		switch(input){
		case 'a':state='U';break;
		case 'b':state='Q';break;
        default:break;
		}
		break;
	case 'Q':
		switch(input){
		case 'a':state='Q';break;
		case 'b':state='Q';break;
        default:break;
		}
		break;
	
	default:state='Q';break;
	}
}
int main(){
	char str[100];
	char*ptr=NULL;
	DFA M;
	while(1){
		M.initialize();
		cout<<"please input the string you want to check;";
		cin>>str;
		ptr=str;
		while(*ptr){
			M.transition(*ptr);
			ptr++;
		}
		if(M.in_terminal_state())
			cout<<str<<"is acceptd by DFA."<<endl;
		else if(M.in_fail_state())
			cout<<str<<"is rejrcted by DFA."<<endl;
		else
			cout<<str<<"is not a complete legal string."<<endl;
	}
	return 0;
}

运行的结果是下面的样子:

突然发现如果输入aas也会出现被DFA接受的情况,一会继续修改,

接下来是最近怎么吃都吃不胖的隔壁宿舍毛毛同学的办法,他是在类中把状态输入了,不过好像得在vs2015里面跑才可以,可能是版本兼容性的问题。我在vs2010里发现里面的等于号显示错误。

ps:我发现这二货在类里面把数据初始化了,注意,类是一种数据类型,定义时系统并不为其分配内存空间。

下面是错误示例,不过还是有参考价值的。

#include<iostream>
#include<string>

using namespace std;

class DFA
{
public:
	char K[4] = { 'S','U','V','Q' };//状态
	char E[2] = { 'a','b' };//符号
	char f[4][2] = { 'U','V','Q','V','U','Q','Q','Q' };//状态矩阵
	char S;//初始状态
	char Q;// 终状态
	
	DFA() {}
	int get_mark1(char x)//搜寻状态矩阵的横坐标
	{
		if ('S' == x)
			return 0;
		else if ('U' == x)
			return 1;
		else if ('V' == x)
			return 2;
		else if('Q' == x)
			return 3;
	}
	int get_mark2(char y)//搜寻状态矩阵的纵坐标
	{
		if ('a' == y)
			return 0;
		else if('b' == y)
			return 1;
	}

};
int main()
{
	DFA dfa;
	string str;
	char x, y;
	x = 'S';
	cin >> str;
	int i = str.length();
	for (int j = 0; j < i; j++)
	{
		y = str[j];
		x = dfa.f[dfa.get_mark1(x)][dfa.get_mark2(y)];
	}
	cout << x << endl;
	return 0;
}

又有一个版本,是我同桌郝宇璇的思路,把各种状态输入进去

#include "iostream"
#include "string"
using namespace std;
struct DFA{
private:
	char state[4];
	char letters[2];
	char f[4][2];
	char s;
	char z;
public:
	DFA();
	bool testDFA(string &s);
};
DFA::DFA(){
	int i;
	cout<<"请输入DFA的状态:";
	for(i=0;i<4;i++){
		cin>>state[i];
	}
	cout<<"请输入DFA字母表:";
	for(i=0;i<2;i++)
		cin>>letters[i];
	cout<<"输入转换后状态:";
	for(i=0;i<4;i++)
		for(int j=0;j<2;j++)
			cin>>f[i][j];
	cout<<"输入初始状态:";
	cin>>s;
	cout<<"输入终态:";
	cin>>z;
}
bool DFA::testDFA(string &s){
	char mstate='S';
	int i=s.length();
	for(int j=0;j<i;j++){
		if(s[j]==letters[0]&&mstate==state[0]){
			mstate=f[0][0];
			continue;
		}
		if(s[j]==letters[0]&&mstate==state[1]){
			mstate=f[1][0];
			continue;
		}
		if(s[j]==letters[0]&&mstate==state[2]){
			mstate=f[2][0];
			continue;
		}
		if(s[j]==letters[0]&&mstate==state[3]){
			mstate=f[3][0];
			break;
		}
		if(s[j]==letters[1]&&mstate==state[0]){
			mstate=f[0][1];
			continue;
		}
		if(s[j]==letters[1]&&mstate==state[1]){
			mstate=f[1][1];
			continue;
		}
		if(s[j]==letters[1]&&mstate==state[2]){
			mstate=f[2][1];
			continue;
		}
		if(s[j]==letters[1]&&mstate==state[3]){
			mstate=f[3][1];
			continue;
		}
	}
	if(mstate=='Q')
		return true;
	else return false;
}
int main(){
	DFA d;
	loop:  string s;
	cout<<"please input a string:"<<endl;
	cin>>s;
	if(d.testDFA(s)){
		cout<<"right"<<endl;
		system("pause");
		goto loop;
	}
	else {
		cout<<"false"<<endl;
		system("pause");
		goto loop;
	}
	return 0;
}

回头再好好研究下其他实现方法。。。。。

未完待续。。。。。。。。



    

发布了27 篇原创文章 · 获赞 19 · 访问量 7457

猜你喜欢

转载自blog.csdn.net/godmanxu/article/details/79823766