用c++实现,NFA到DFA的转换,请教高手。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用c++实现,NFA到DFA的转换,请教高手。相关的知识,希望对你有一定的参考价值。

谢谢啦。
下面的这个好像不对。
谁能讲一下大致思想就好。

参考技术A 基本思想:
寻找每个节点的e-closure. 因为NFA和DFA的区别就是e边。

具体算法去看编译龙书中文版的79-80页。
参考技术B #include "stdafx.h"
#include <vector>
#include <string>
#include <queue>
#include <iostream>

using namespace std;

struct Transform

friend class FA;
char state1;
char letter;
char state2;
bool operator!=(char ch);
friend istream& operator>>(istream& in,Transform& t);
;
struct ChangeTable

string state;
int flag;
vector<string> changestate;
;
bool Transform::operator!=(char ch)

return state1!=ch||letter!=ch||state2!=ch;

namespace std

istream& operator>>(istream& in,Transform& t)

return in>>t.state1>>t.letter>>t.state2;


class FA

private:
vector<char> state; //状态集
vector<char> table; //输入字母表
vector<Transform> fun; //状态变迁函数
char q0; //初态
vector<char> Z; //终态集
string GetChangeState(char state1,char table);
void RemoveRepeat(string &str); //消除重复元素
private:
vector<ChangeTable> changetable;
bool IsInChangeTable(string str);
int GetIndexofChangeTable(); //找出第一个flag为0的索引
int GetIndexofChangeTable(string str); //找出str 在表中的索引
void GetChangeTable();
void OutputChangeTable();
public:
// FA()
void Deterministic(FA &dfa);
void input();
void output();

;
void FA::RemoveRepeat(string &str)

string mid;
string::size_type idx;
string::iterator pos;
for(pos=str.begin();pos!=str.end();++pos)

idx=mid.find(*pos);
if(idx==string::npos)
mid+=*pos;

str=mid;

bool FA::IsInChangeTable(string str)

vector<ChangeTable>::iterator pos;
for(pos=changetable.begin();pos!=changetable.end();++pos)
if((*pos).state==str)
return 1;
return 0;

int FA::GetIndexofChangeTable()

int index;
for(index=0;index<changetable.size();++index)
if(changetable[index].flag==0)
return index;
return -1;

int FA::GetIndexofChangeTable(string str)

int index;
for(index=0;index<changetable.size();++index)
if(changetable[index].state==str)
return index;
return -1;

string FA::GetChangeState(char state1,char table)

string str;
vector<Transform>::iterator pos;
for(pos=fun.begin();pos!=fun.end();++pos)
if((*pos).state1==state1&&(*pos).letter==table)
str+=(*pos).state2;
RemoveRepeat(str);
return str;

void FA::input()

char ch;
Transform tran;
cout<<"input the set of state,ended with '#'"<<endl;
cin>>ch;
while(ch!='#')

state.push_back(ch);
cin>>ch;

cout<<"input the set of input's table,ended with '#'"<<endl;
cin>>ch;
while(ch!='#')

table.push_back(ch);
cin>>ch;


cout<<"input the transform of function,formation is state1 letter state1 "<<endl;
cout<<"ended with '# # #'"<<endl;
cin>>tran;
while(tran!='#')

fun.push_back(tran);
cin>>tran;

cout<<"input the state of Initlization table"<<endl;
cin>>q0;

cout<<"input the set of termination,ended with '#'"<<endl;
cin>>ch;
while(ch!='#')

Z.push_back(ch);
cin>>ch;


void FA::GetChangeTable()

ChangeTable ct,midct;
string str;
string mid;
queue<string> q;
vector<char>::iterator pos;
string::iterator p;
ct.state=string(1,q0); //从初始状态开始
ct.flag=0;
changetable.push_back(ct);
int index=GetIndexofChangeTable();
while(index!=-1)

changetable[index].flag=1;
str=changetable[index].state; //弹出状态

for(pos=table.begin();pos!=table.end();++pos) //每种输入状态

mid.erase();
for(p=str.begin();p!=str.end();++p) //每个状态的每个字符

mid+=GetChangeState(*p,*pos);
RemoveRepeat(mid);


changetable[index].changestate.push_back(mid);

if(!mid.empty()&&!IsInChangeTable(mid))

ct.state=mid;
ct.flag=0;
changetable.push_back(ct);



index=GetIndexofChangeTable();


void FA::OutputChangeTable()

vector<ChangeTable>::iterator pos;
for(pos=changetable.begin();pos!=changetable.end();++pos)
cout<<""<<(*pos).state<<" ";
for(int i=0;i<(*pos).changestate.size();i++)
cout<<""<<(*pos).changestate[i]<<" ";
cout<<endl;


void FA::Deterministic(FA &dfa)

GetChangeTable();
//OutputChangeTable(); //输出中间状态转换表
dfa.table=table;
int size=0;
while(size<changetable.size()) //求状态集

dfa.state.push_back('A'+size);
size++;

dfa.q0='A'; //求初态
Transform tran;
vector<string>::iterator pos;
vector<char>::iterator p;
for(int i=0;i<changetable.size();++i)

tran.state1='A'+i;
for(p=table.begin(),pos=changetable[i].changestate.begin();pos!=changetable[i].changestate.end();++pos,++p)

tran.letter=*p;
int index=GetIndexofChangeTable(*pos);
tran.state2='A'+index;
if(index!=-1)
dfa.fun.push_back(tran);

//下面来求终态集
string mid;
string str=changetable[i].state;
for(p=Z.begin();p!=Z.end();++p)

mid.erase();
mid+=*p;

int idx=str.find(mid);
if(idx!=string::npos)
dfa.Z.push_back('A'+i);



void FA::output()

vector<char>::iterator pos;
cout<<"M=Vn,Vt,F,q0,Z,其中:"<<endl;
cout<<"Vn=";
for(pos=state.begin();pos!=state.end()-1;++pos)
cout<<*pos<<",";
cout<<*pos<<""<<endl;
cout<<"Vt=";
for(pos=table.begin();pos!=table.end()-1;++pos)
cout<<*pos<<",";
cout<<*pos<<""<<endl;

cout<<"F is:"<<endl;
for(std::vector<Transform>::iterator p=fun.begin();p!=fun.end();++p)
cout<<"f("<<(*p).state1<<","<<(*p).letter<<")="<<(*p).state2<<endl;

cout<<"q0="<<q0<<endl;

cout<<"Z=";
for(pos=Z.begin();pos!=Z.end()-1;++pos)
cout<<*pos<<",";
cout<<*pos<<""<<endl;


int main(int argc, char* argv[])

FA nfa,dfa;
nfa.input();
nfa.output();
nfa.Deterministic(dfa);
cout<<"转换成DFA为:"<<endl;
dfa.output();
return 0;

来源:http://topic.csdn.net/t/20041024/23/3486893.html

什么是子集构造法

参考技术A 子集构造是NFA(Non-Deterministic Finite Automaton, 非确定有穷自动机)转DFA(Deterministic Finite Automaton)时所使用的用于消除 epsilon-transition(epsilon转换. 那个字符打不出来, 你懂的) 的方法.

其方法如下.
设有NFA的M, 将其转换为DFA的 `M.

M的初始状态的epsilon-closure(epsilon-闭包)作为 `M的初始状态. 而后, 在某个转换上, 设该转换为 a-transition, 那么, 构造 Sa = t| 对原状态集合S中的一些状态s, 存在通过a-transition到t的转换. 再构造Sa的闭包 `Sa. 如此一直构造, 直到没有新的状态构造出来为止, 此即子集构造.本回答被提问者和网友采纳

以上是关于用c++实现,NFA到DFA的转换,请教高手。的主要内容,如果未能解决你的问题,请参考以下文章

C语言实现NFA转DFA

编译原理:怎么用子集法将NFA转换成DFA? 用图4.16的NFA举例子

请教用MDK编译出现dfa.axf: Error: L6218E: Undefined symbol

NFA到DFA的转换及DFA的简化

从正则表达式到 NFA 到 DFA 到最简 DFA

NFA 到 DFA 转换的简明描述?