不确定有穷状态自动机的确定化实验报告Word文档格式.docx

上传人:b****6 文档编号:17764148 上传时间:2022-12-09 格式:DOCX 页数:17 大小:269.30KB
下载 相关 举报
不确定有穷状态自动机的确定化实验报告Word文档格式.docx_第1页
第1页 / 共17页
不确定有穷状态自动机的确定化实验报告Word文档格式.docx_第2页
第2页 / 共17页
不确定有穷状态自动机的确定化实验报告Word文档格式.docx_第3页
第3页 / 共17页
不确定有穷状态自动机的确定化实验报告Word文档格式.docx_第4页
第4页 / 共17页
不确定有穷状态自动机的确定化实验报告Word文档格式.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

不确定有穷状态自动机的确定化实验报告Word文档格式.docx

《不确定有穷状态自动机的确定化实验报告Word文档格式.docx》由会员分享,可在线阅读,更多相关《不确定有穷状态自动机的确定化实验报告Word文档格式.docx(17页珍藏版)》请在冰豆网上搜索。

不确定有穷状态自动机的确定化实验报告Word文档格式.docx

stdlib.h>

malloc.h>

stdio.h>

conio.h>

#defineN20//用于控制数组的最大长度

//用邻接表存储NFA和DFA的状态字母后继

typedefstructadjvex

{//定义邻接表的邻接点域的数据表示

charnextstate;

//头结点状态的后继状态

chararc;

//弧

structadjvex*next;

//指向该头结点状态的下一个后继状态的指针

}adjvex;

typedefstructheadvex

{//定义邻接表的头部的数据表示

charstate;

//状态

adjvex*firstarc;

//指向第一个后继状态的指针

}headvex;

//定义两个邻接表的头部,为全局数组

headvexNFA[N];

//用邻接表存储的NFA

headvexDFA[N];

//用邻接表存储的DFA

charAlp[N];

//存储需要输入的行为集,即字母表

voidmain()

{

voiddesignby();

//函数声明

voidclosure(chars,charset[N]);

//求e_closure闭包函数

voidSpecial(charDFA_start[N],charnew_state[N][N]);

//确定化函数

designby();

inti,j;

charNFA_start[N];

//存放NFA的初态

charDFA_start[N];

//存放DFA的初态

charNFA_final[N];

//存放NFA的终态

charDFA_final[N];

//存放DFA的终态

charnew_state[N][N];

//存放DFA的I的二维数组每一行为一个原NFA的一个新的状态集,e-closure(move(I,a))

for(i=0;

i<

N;

i++)

{

NFA[i].state='

#'

;

NFA[i].firstarc=NULL;

DFA[i].state='

DFA[i].firstarc=NULL;

Alp[i]='

NFA_start[i]='

DFA_start[i]='

NFA_final[i]='

DFA_final[i]='

for(j=0;

j<

j++)

new_state[i][j]='

}

intm,n;

printf("

请输入NFA:

状态的个数:

[]\b\b\b"

);

scanf("

%d"

&

n);

fflush(stdin);

状态转换个数:

m);

请输入各状态:

(状态,0/1/2),终态输2,非初终态输1,初态输0.\n"

//创建邻接表

intf;

n;

i++)//n个状态的输入,依次存储到已开辟空间的邻接表头结点中,并根据状态分类装入NFA的初态终态数组中.

printf("

状态%d:

"

i+1);

scanf("

%c,%d"

NFA[i].state,&

f);

fflush(stdin);

if(f==0)//输入状态若为初态,依次存入到NFA_start[N]数组中

{

for(j=0;

N&

&

NFA_start[j]!

='

j++);

NFA_start[j]=NFA[i].state;

}

if(f==2)//输入状态若为终态,依次存入到NFA_final[N]数组中

NFA_final[j]!

NFA_final[j]=NFA[i].state;

输入完毕!

\n\n"

请输入状态转换函数:

(状态1,状态2,输入字符)\n"

adjvex*p;

//定义一个指向adjvex的指针p

charfrom,to,arc;

intk;

m;

i++)//m个转换函数的输入,开辟空间并依次存储至相应头结点状态的邻接表中.

状态转换%d:

%c,%c,%c"

from,&

to,&

arc);

p=(adjvex*)malloc(sizeof(adjvex));

p->

nextstate=to;

arc=arc;

for(k=0;

NFA[k].state!

=from;

k++);

//结束时k的值即为匹配状态所在的头结点

next=NFA[k].firstarc;

//前插法插入结点到头结点后

NFA[k].firstarc=p;

if(arc!

$'

)//输入字符不为空,保存到Alps[N]字母表中

Alp[j]!

j++)

if(arc==Alp[j])

break;

//存在则跳出,结束不保存

//上循环结束的两个可能:

1、该输入字符已经存在于字母表中不存跳出,则下面的if也不会成立;

//2、从0开始到#结束都没找不到一样的字母,结束for,记下了j.

if(Alp[j]=='

)Alp[j]=arc;

//求所有NFA_start[N]中所有初态的closure形成总的初态DFA_start[N]

//charstart[N][N];

//for(i=0;

//for(j=0;

//start[i][j]='

NFA_start[i]!

i++)//依次对每个NFA初态求等价状态放在二维数组中

//closure(NFA_start[i],DFA_start);

/*

i++)//将start二维数组变到一位数组DFA_start[N]中

start[i][j]!

k=0;

for(k=0;

DFA_start[k]!

=start[i][j]&

DFA_start[k]!

k++);

if(DFA_start[k]=='

)DFA_start[k]=start[i][j];

elsecontinue;

*/

k=0;

while(NFA[k].state!

=NFA_start[0])

k++;

closure(NFA[k].state,DFA_start);

//求初态的e_closure闭包

//for(intz=0;

z<

z++)

//printf("

%4c%4c\n"

NFA_start[z],DFA_start[z]);

Special(DFA_start,new_state);

//有DFA_start[N],即为new_state[0]通过对NFA[N]邻接表依次求

//for(z=0;

//{

//printf("

%s\n"

new_state[z]);

//}

i<

N&

new_state[i][0]!

i++)//寻找DFA的终态

j<

new_state[i][j]!

for(f=0;

f<

NFA_final[f]!

f++)

if(new_state[i][j]==NFA_final[f])

{

DFA_final[k]=i+65;

k++;

}

if(new_state[i][j]==NFA_final[f])

break;

//NFA和DFA的输出:

确定化后的DFA如下所示:

\n"

"

Alp[i]!

i++)

%3c"

Alp[i]);

初终"

DFA[i].state!

i++)//以矩阵形式输出DFA

%4c"

DFA[i].state);

Alp[j]!

p=DFA[i].firstarc;

while(p)

{

if(p->

arc==Alp[j])

printf("

p->

nextstate);

else

p=p->

next;

}

if(p==NULL)

printf("

k<

DFA_final[k]!

k++)

if(DFA[i].state==DFA_final[k])

if(DFA_final[k]=='

printf("

0"

else

1"

每个新的状态对应的原状态子集如下:

//输出对应的NFA子集

i+65);

{"

new_state[i][j+1]!

%c,"

new_state[i][j]);

%c}"

新的终态如下:

DFA_final[i]!

DFA_final[i]);

}

voidclosure(chars,charset[N])//找一个状态s经过任意连续个的空弧所到达的等价状态的集合set[N](包括自身即为0条空弧)

set[i]!

i++)//将自身存储到set[N]中,0条空弧

if(set[i]==s)

break;

if(set[i]=='

set[i]=s;

for(j=0;

NFA[j].state!

=s;

//查找相应状态所在的邻接表的头结点状态位置j

p=NFA[j].firstarc;

//指针p指向该头结点状态的第一个后继状态

while(p)

if(p->

arc=='

closure(p->

nextstate,set);

//若为空弧的话,递归进入该后继状态所对应的头结点状态处依次查找其空弧后继,查找结束回到上一层后继状态继续查找

p=p->

//查看该头结点状态的下一个后继状态

return;

voidmove(charFrom[N],chararc,charTo[N])//找一个状态集From[N]的所有状态的arc后继状态的集合To[N]

inti,j,k,t=0;

j=0;

//首先定义j为0

From[i]!

i++)//依次对其中的每一个状态求move,直至结束

NFA[k].state!

=From[i];

p=NFA[k].firstarc;

while(p)//逐个后继状态往后判断后继结束,每次将弧为arc的状态保存到To[N]中

if(p->

arc==arc)

for(k=0;

k<

To[k]!

k++)

if(To[k]==p->

nextstate)

{

p=p->

break;

//该状态若已存在To[N]中,跳出循环不保存,移动指针查看下一个后继状态

}

if(To[k]=='

)//直达结束没有发现已经存入,

To[t++]=p->

nextstate;

elsep=p->

voidOrder(chara[N])

//由小到大对数组中的每个字符排序

chartemp;

a[i]!

for(j=i+1;

a[j]!

if(a[j]<

a[i])

temp=a[i];

a[i]=a[j];

a[j]=temp;

voidSpecial(charDFA_start[N],charnew_state[N][N])

charTo1[N],To2[N];

charorder1[N],order2[N];

To1[i]='

To2[i]='

DFA_start[i]!

new_state[0][i]=DFA_start[i];

//将DFA_start[N]复制到new_state[0],作为一个状态

intst,k,t;

for(st=0;

st<

new_state[st][0]!

st++)

DFA[st].state=st+65;

for(i=0;

Alp[i]!

To1[k]='

To2[k]='

//每次使用TO1,To2都要清除原有数据

move(new_state[st],Alp[i],To1);

To1[j]!

j++)//循环求状态集的closure闭包(求每一个状态的closure时,都会对上一个状态得到的To2[N]从头找不相同的存进去)

closure(To1[j],To2);

new_state[j][0]!

{//将new_state和closure(move(I,a))转存到两个新数组中,排序比较是否已经存在此状态集合,以防出错

order1[k]=new_state[j][k];

order2[k]=To2[k];

Order(order1);

Order(order2);

//比较是否相等

order1[k]!

order2[k]!

if(order1[k]!

=order2[k])break;

if(order1[k]==order2[k])break;

//前面比较一直相等,最后第k个也为#,同时结束,说明相同

if(new_state[j][0]=='

)//不存在与新状态相等的状态,将其存入最后一行new_state[j]

for(t=0;

t<

To2[t]!

t++)

new_state[j][t]=To2[t];

p=(adjvex*)malloc(sizeof(adjvex));

//为这个状态转换创建一个结点

p->

nextstate=j+65;

arc=Alp[i];

next=DFA[st].firstarc;

DFA[st].firstarc=p;

voiddesignby()

\n\t\t编译原理实验

(二)\n\n"

\t实验名称:

不确定有穷状态自动机的确定化.\n"

\t实验目的:

输入:

非确定有穷状态自动机NFA\n"

\t输出:

确定化的有穷状态自动机DFA\n\n"

\t姓名:

鲁庆河(E01214055)\n"

\t日期:

2015.05.12--2015.05.15\n"

getch();

b)截图:

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

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

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

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