实验一利用子集法构造DFAWord文档下载推荐.docx

上传人:b****5 文档编号:17282801 上传时间:2022-11-30 格式:DOCX 页数:42 大小:524.64KB
下载 相关 举报
实验一利用子集法构造DFAWord文档下载推荐.docx_第1页
第1页 / 共42页
实验一利用子集法构造DFAWord文档下载推荐.docx_第2页
第2页 / 共42页
实验一利用子集法构造DFAWord文档下载推荐.docx_第3页
第3页 / 共42页
实验一利用子集法构造DFAWord文档下载推荐.docx_第4页
第4页 / 共42页
实验一利用子集法构造DFAWord文档下载推荐.docx_第5页
第5页 / 共42页
点击查看更多>>
下载资源
资源描述

实验一利用子集法构造DFAWord文档下载推荐.docx

《实验一利用子集法构造DFAWord文档下载推荐.docx》由会员分享,可在线阅读,更多相关《实验一利用子集法构造DFAWord文档下载推荐.docx(42页珍藏版)》请在冰豆网上搜索。

实验一利用子集法构造DFAWord文档下载推荐.docx

};

intn;

//n:

边数

intnk=0;

//空字符转换的边数

intfirst,accept;

//开始状态,接受状态

charalpha[100];

//输入字母表,#代表空串

intnumof_char=0;

//字母表中的字符个数

intuseof_char[256];

//该转换字符是否用过

intf[200];

//状态属性标志:

0表示始态,1表示接受态,-1表示中间态

StateDFA[100];

//DFA状态集

intuseof_DFA[100];

//标志构造出来的状态是否已存在

intnumof_Dtran=0;

//最后得到的DFA中的状态数

charDtran[100][100];

//DFA状态转换表

voidinput()

{

inti,s,e;

charch;

cout<

<

"

请输入转换的有向边数n:

endl;

cin>

>

n;

请输入NFA的开始状态:

first;

请输入NFA的接受状态(输入-1结束):

memset(f,-1,sizeof(f));

memset(useof_char,0,sizeof(useof_char));

f[first]=0;

accept;

while(accept!

=-1)

f[accept]=1;

cin>

请输入NFA,起点,终点,转换字符('

#'

表示空字符):

intk=0;

for(i=0;

i<

i++)

s>

e>

ch;

E[i].start=s;

E[i].end=e;

E[i].c=ch;

if(ch!

='

&

!

useof_char[ch])

{

alpha[numof_char++]=ch;

useof_char[ch]=1;

}

if(ch=='

Ekong[nk].start=s;

Ekong[nk].end=e;

Ekong[nk].c=ch;

nk++;

Statemove(StateT,chars)//c!

Statetemp;

temp.count=0;

temp.mark=T.mark;

inti,j=0,k=0;

T.count;

j=0;

while(j<

n)

if(E[j].start==T.H[i]&

E[j].c==s)

{temp.H[temp.count++]=E[j].end;

j++;

returntemp;

voidarriveBynone(intt,intresult[],int&

num)//搜索状态t通过一个或多个空字符到达的状态,结果存在result中

intm=0;

num=0;

stack<

int>

S;

S.push(t);

intj;

while(!

S.empty())

j=S.top();

S.pop();

m=0;

while(m<

nk)

if(Ekong[m].start==j)

result[num++]=Ekong[m].end;

S.push(Ekong[m].end);

m++;

boolcheck(inti,StateT)//判断状态i是否在T中

for(j=0;

j<

j++)

if(T.H[j]==i)

returntrue;

returnfalse;

Stateclosure(StateT)//求闭包

STACK;

inti,j,k;

STACK.push(T.H[i]);

temp.H[i]=T.H[i];

temp.count=T.count;

while(!

STACK.empty())

{

intt=STACK.top();

STACK.pop();

//搜索状态t通过一个或多个空字符到达的状态

intsearch_result[100];

intnum;

arriveBynone(t,search_result,num);

for(j=0;

num;

if(!

check(search_result[j],temp))

temp.H[temp.count++]=search_result[j];

STACK.push(search_result[j]);

for(k=0;

k<

temp.count;

k++)

if(f[temp.H[k]]==1)

temp.flag=1;

break;

if(f[temp.H[k]]==0)

temp.flag=0;

break;

sort(temp.H,temp.H+temp.count);

numof_Dtran;

if(temp.count!

=DFA[i].count)

continue;

sort(DFA[i].H,DFA[i].H+DFA[i].count);

DFA[i].count;

if(DFA[i].H[j]!

=temp.H[j])

if(j>

temp.mark=DFA[i].mark;

intcheck_inDFA()//检查DFA中是否存在未被标记的状态,有则返回标号,否则返回-1

inti;

for(i=0;

useof_DFA[i])

returni;

return-1;

boolcheck_whetherin_DFA(StateT)

inti,j;

sort(T.H,T.H+T.count);

if(T.count!

=T.H[j])

returntrue;

if(i>

=numof_Dtran)

returnfalse;

else

voidchild_method()

intm,n;

for(m=0;

m<

100;

m++)

for(n=0;

n<

n++)

Dtran[m][n]='

;

for(m=0;

DFA[m].flag=-1;

StateS0,U;

S0.flag=0;

S0.count=1;

S0.H[0]=first;

StateT;

T=closure(S0);

T.mark=0;

T.flag=0;

DFA[numof_Dtran++]=T;

memset(useof_DFA,0,sizeof(useof_DFA));

intj=check_inDFA();

intk;

while(j!

useof_DFA[j]=1;

for(k=0;

numof_char;

U=closure(move(DFA[j],alpha[k]));

//ifU不在DFA中

check_whetherin_DFA(U))

{U.mark=numof_Dtran;

DFA[numof_Dtran++]=U;

Dtran[DFA[j].mark][U.mark]=alpha[k];

j=check_inDFA();

voidprint()

cout<

:

DFA[i].H[j]<

"

if(DFA[i].flag==1)

此为DFA的接受状态"

if(DFA[i].flag==0)

此为DFA的开始状态"

{if(Dtran[i][j]!

{cout<

->

By"

Dtran[i][j]<

voidjudge(stringch)

inti,j,k;

intnum=ch.length();

Statetemp;

k=0;

if(Dtran[k][j]==alpha[i])

temp=DFA[j];

k=j;

break;

if(temp.flag!

=1)

字符串"

ch<

无法由该DFA得到"

可以由该DFA得到"

int_tmain(intargc,_TCHAR*argv[])

input();

child_method();

print();

strings;

while(cin>

s)

judge(s);

system("

pause"

);

return0;

5、实验结果

6、算法分析

使用子集构造法对非确定有限自动机进行确定化的过程中存在大量重复计算的问题。

为解决此问题,基于非确定有限自动机的特点并针对子集构造法的不足,提出了一种优化的非确定有限自动机确定化算法。

首先定义了识别符的有效引出状态集概念并证明了ε-closure的并定理以保证算法的正确性,其次给出了用于避免重复计算的识别符的有效引出状态集的构造子算法和单状态集的ε-closure的求算子算法,基于这两个子算法给出了优化的非确定有限自动机确定化算法,最后将算法应用于实例,实验结果表明计算量远小于子集构造法的计算量。

相比子集构造法,算法能更有效地对非确定有限自动机进行确定化。

七、实验小结

以前上课时有许多的问题并没有真正的认识到,但通过这次实验,使我掌握了许多更重要的知识点。

通过实验,我们可以知道将NFA转换成接受同样语言的DFA的算法称为子集构造算法。

NFA变换到DFA的基本思想是:

让DFA的每个状态对应NFA的一个状态集。

实验实现了NFA到DFA的转换。

实验二THOMPSON算法的实现

掌握将正规表达式转换为NFA的方法和过程

3、实验要求及内容

1.输入一个正规表达式,输出一个接受同一语言的NFA

2.采用C++语言,实现该算法

3.编制测试程序

4.调试程序

计算机、Windows操作系统、VisualC++程序集成环境。

四、程序代码

Thompson.h"

voidmain()

stringRegular_Expression="

(a|b)*abb"

cellNFA_Cell;

input(Regular_Expression);

//调试需要先屏蔽

Regular_Expression=add_join_symbol(Regular_Expression);

Regular_Expression=postfix(Regular_Expression);

NFA_Cell=express_2_NFA(Regular_Expression);

Display(NFA_Cell);

cellexpress_2_NFA(stringexpression)

intlength=expression.size();

charelement;

cellCell,Left,Right;

stack<

cell>

for(inti=0;

length;

element=expression.at(i);

switch(element)

case'

|'

Right=STACK.top();

STACK.pop();

Left=STACK.top();

Cell=do_Unite(Left,Right);

STACK.push(Cell);

*'

Cell=do_Star(Left);

+'

Cell=do_Join(Left,Right);

default:

Cell=do_Cell(element);

}

cout<

处理完毕!

Cell=STACK.top();

STACK.pop();

returnCell;

celldo_Unite(cellLeft,cellRight)

cellNewCell;

NewCell.EdgeCount=0;

edgeEdge1,Edge2,Edge3,Edge4;

stateStartState=new_StateNode();

stateEndState=new_StateNode();

Edge1.StartState=StartState;

Edge1.EndState=Left.EdgeSet[0].StartState;

Edge1.TransSymbol='

Edge2.StartState=StartState;

Edge2.EndState=Right.EdgeSet[0].StartState;

Edge2.TransSymbol='

Edge3.StartState=Left.EdgeSet[Left.EdgeCount-1].EndState;

Edge3.EndState=EndState;

Edge3.TransSymbol='

Edge4.StartState=Right.EdgeSet[Right.EdgeCount-1].EndState;

Edge4.EndState=EndState;

Edge4.TransSymbol='

//先将Left和Right的EdgeSet复制到NewCell

cell_EdgeSet_Copy(NewCell,Left);

cell_EdgeSet_Copy(NewCell,Right);

//将新构建的四条边加入EdgeSet

NewCell.EdgeSet[NewCell.EdgeCount++]=Edge1;

NewCell.EdgeSet[NewCell.EdgeCount++]=Edge2;

NewCell.EdgeSet[NewCell.EdgeCount++]=Edge3;

NewCell.EdgeSet[NewCell.EdgeCount++]=Edge4;

//构建NewCell的启示状态和结束状态

NewCell.StartState=StartState;

NewCell.EndState=EndState;

returnNewCell;

//处理ab

celldo_Join(cellLeft,cellRight)

Right.EdgeCount;

if(Right.EdgeSet[i].StartState.StateNpare(Right.StartState.StateName)==0)

Right.EdgeSet[i].StartState=Left.EndState;

STATE_NUM--;

elseif(Right.EdgeSet[i].EndState.StateNpare(Right.StartState.StateName)==0)

Right.EdgeSet[i].EndState=Left.EndState;

Right.StartState=Left.EndState;

cell_EdgeSet_Copy(Left,Right);

Left.EndState=Right.EndState;

returnLeft;

celldo_Star(cellCell)

//构建边

Edge1.EndState=EndState;

Edge2.StartState=Cell.EndState;

Edge2.EndState=Cell.StartState;

Edge3.StartState=StartState;

Edge3.EndState=Cell.StartState;

Edge4.StartState=Cell.EndState;

//构建单元

cell_EdgeSet_Copy(NewCell,Cell);

celldo_Cell(charelement)

edgeNewEdge;

stateStartState=new_StateNode();

NewEdge.StartState=StartState;

NewEdge.EndState=EndState;

NewEdge.TransSymbol=element;

NewCell.EdgeSet[NewCell.EdgeCount++]=NewEdge;

NewCell.StartState=NewCell.EdgeSet[0].StartState;

NewCell.EndState=NewCell.EdgeSet[0].EndState;

//EdgeCount此时为1

voidcell_EdgeSet_Copy(cell

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 数学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1