DFA的编程实现含源代码实验报告剖析Word格式.docx

上传人:b****6 文档编号:20936136 上传时间:2023-01-26 格式:DOCX 页数:17 大小:186.45KB
下载 相关 举报
DFA的编程实现含源代码实验报告剖析Word格式.docx_第1页
第1页 / 共17页
DFA的编程实现含源代码实验报告剖析Word格式.docx_第2页
第2页 / 共17页
DFA的编程实现含源代码实验报告剖析Word格式.docx_第3页
第3页 / 共17页
DFA的编程实现含源代码实验报告剖析Word格式.docx_第4页
第4页 / 共17页
DFA的编程实现含源代码实验报告剖析Word格式.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

DFA的编程实现含源代码实验报告剖析Word格式.docx

《DFA的编程实现含源代码实验报告剖析Word格式.docx》由会员分享,可在线阅读,更多相关《DFA的编程实现含源代码实验报告剖析Word格式.docx(17页珍藏版)》请在冰豆网上搜索。

DFA的编程实现含源代码实验报告剖析Word格式.docx

能将保存在内存变量中的DFA写入DFA文件,也能将DFA文件读入内存中。

(思考:

对稀疏DFA(转换表中为空的地方较多)或用“或”表达转换的DFA(如下的测试用例三),如何改进DFA转换表的表达。

(3)DFA的正确性检查:

检查所有集合的元素的唯一性。

检查“开始状态”是否唯一,并是否包含在“状态集”中。

检查“接受状态集”是否为空,并是否包含在“状态集”中。

检查“状态转换表”是否满足DFA的要求。

检查“状态转换表”并非填满时的处理是否得当…

(4)DFA的语言集列表显示:

输入待显示的字符串的最大长度N,输出以上定义的DFA的语言集中长度≤N的所有规则字符串。

(提示:

注意算法中while循环的次数)

(5)DFA的规则字符串判定:

输入(或用字符集随机生成)一个字符串,模拟DFA识别字符串的过程判定该字符串是否是规则字符串(属于DFA的语言集)。

测试用例:

DFA

(一)

DFA

(二)

DFA(三)

实验要求:

按照《编译原理及实践》参考书第二章中描述的“while循环+双层case选择”的算法编程实现一般的DFA。

要求能通过以上三个测试用例的测试。

完成内容中

(1)(5)部分,可得C。

完成内容中

(1)

(2)(5)部分,可得B。

完成内容中

(1)

(2)(4)(5)部分,可得A。

完成全部内容,可得奖励。

判定算法概要:

准备:

开始状态s0,接受状态集F,状态转换表T(s,c),sÎ

S,cÎ

S

c=getchar();

s=开始状态s0;

while(c!

=EOF)//输入未结束则循环…

{

s=T(s,c);

if(s==NULL)

error();

}

if(sÎ

接受状态集F)

accept();

else

error();

通用DFA存储格式的建议:

(用以上的第三个测试DFA为例)

3//字符集中的字符个数(以下两行也可合并成一行)

/*o//以空格分隔的字符集。

O代表任意非/和*的字符

5//状态个数(以下两行也可合并成一行)

12345//状态编号。

若约定总是用从1开始的连续数字表示,则此行可省略

1//开始状态的编号。

若约定为1,则此行可省略

1//结束状态个数。

5//结束状态的编号

2-1-1//状态1的所有出去的转换。

按字符集中的字符顺序给出。

-1表示出错状态

-13-1

343

543

-1-1-1

实验报告:

同时上交纸质报告与电子版报告。

纸质报告以实验分析、实验中遇到的问题及解决方法、实验测试(含屏幕截图)、实验心得等为主,不得大量引用源程序(引用源程序总行数不得超过100行)。

电子版报告以源程序、测试用例、输出文件等为主,包括纸质报告的电子版,须确保提并的源程序能编译运行,否则不要上交。

电子版请发送到****************,邮件标题请写明学号、姓名与实验编号,形如:

<

实验一>

<

学号>

姓名>

不得抄袭实验报告与源程序,否则后果自负!

提高内容:

(1)图形化的用户界面;

(2)任意DFA的状态转换图、状态转换表的图形绘制;

 

附实验报告源码

实验一DFA的编程实现

实验分析:

DFA的初始化

一个DFA的基本信息状态集、字符集、开始状态、结束状态集、状态转换表;

在程序中状态集、字符集、开始状态、结束状态集都用string类型来表示,即可不用考虑用户输入内容的长度。

但缺点是字符集只能是字符而不可以是字符串。

状态转换表:

为三个字符的字符串,第一个为当前状态,第二个为输入字符,第三个为下一状态。

用vector容器存放转换函数的内容

字符串判断

初始化一个DFA,后可以通过一下算法判断一个字符串是否符合该DFA。

开始状态s0,接受状态集F,状态转换表T(s,c),sS,c

if(s接受状态集F)

error();

在实际编写代码中的体现为

voididentify()//判断字符串

{

cout<

"

请输入字符串"

endl;

stringstr;

cin>

>

str;

inti=0;

charpresent=StartStates;

while(i<

str.length())

{

present=move(present,str[i]);

//move函数即去遍历转换表,返回下个状态

if(present=='

N'

)//N即为move返回错误的状态,

{

break;

}

i++;

}

if(FinalStates.find(present)!

=FinalStates.npos)//如果返回的状态用find函数属于最终状态集则表示识别

cout<

该自动机识别此字符串"

else

该自动机不识别此字符串"

}

对DFA的存储与读写

将DNF的信息写入文件中,

第一行:

字符集;

第二行:

状态集;

第三行:

开始状态;

第四行:

结束状态集;

以下行写入状态转换表

按照既定的规定读取文件

中的数据将其赋值,然后

初始化DFA即可;

DFA的语言集列表显示:

这一个模块应该是这个实验中比较难的一部分了。

我并没有使用while循环的这个做法。

而是用函数递归,通过所有字符集的路径去遍历整个DFA。

最后将符合条件的字符串输出;

voidTraversal(charpresent,intN,stringstrass="

)//遍历DFA的语言集列表

if(present=='

||N<

0)//若路径已经大于N或者当前状态错误,停止递归

return;

N--;

=FinalStates.npos)

该自动机识别字符串:

strass<

for(inti=0;

i<

Alphabet.length();

i++)

stringtemp;

temp=strass;

strass+=Alphabet[i];

Traversal(move(present,Alphabet[i]),N,strass);

strass=temp;

递归终止条件的判断。

当N--时,N小于0,或者遍历到无路可走是便终止

遇到的问题:

对于递归的终止条件写得不够明确。

递归前对字符串赋值strass赋值,递归后应该还原,这一点没有想到。

调试了很久。

总结,对递归的具体编写还是不熟悉。

目前的代码,字符集和状态只能是一个字符,若要优化可以用vector<

string>

容器存储即可;

实验用例:

实验结果:

判断字符串:

显示小于N的语言集:

读取DFA文件:

实验总结:

在这次实验中,学习对一般的DFA的表达方法与编程实现方法。

对课本提供的算法有了更深刻的认识。

在编写和调试代码的过程中对自身的编程能力也有了很大的提高。

对自动机和其识别语言有了更透彻的理解。

在动手编程之前一定要好好明确实验的理论准备和思路的理清,能帮助我们在实验过程中少走更多的弯路。

总之在这次实验中收获很多,提高了动手能力和分析问题的能力。

源代码:

//构造一个DFA

#include<

iostream>

vector>

fstream>

usingnamespacestd;

classTransitionTable

public:

charpresent;

//当前状态

charnext;

//下一状态

charinput;

//输入字符

TransitionTable(charP,charI,charD)

present=P;

next=D;

input=I;

};

classDFA

DFA()

1、手动输入,2、读取txt文件"

intselect;

select;

if(select==1)

inti();

if(select==2)

read();

stringStates;

//状态集

charStartStates;

//开始状态

stringFinalStates;

//结束状态集

stringAlphabet;

//字符集

vector<

TransitionTable>

Trans;

//转换函数

voidinti()//初始化自动机

请输入有限状态集S:

States;

请输入字符集A:

Alphabet;

请输入转换函数MOVE--格式为:

当前状态-输入字符-下一状态:

(输入#结束输入)"

intj=0;

while(true)

charinput[4];

cin>

input;

if(strcmp(input,"

#"

)==0)

TransitionTableTemp(input[0],input[1],input[2]);

Trans.push_back(Temp);

请输入开始状态集S0:

StartStates;

请输入结束状态集F:

FinalStates;

voididentify()//识别字符串

请输入字符串:

)//N即为move返回错误的状态,

;

charmove(charP,charI)//move转换函数

Trans.size();

if(Trans[i].present==P&

&

Trans[i].input==I)

returnTrans[i].next;

return'

voidread()//从txt文件中读取DNF的信息

chartemp[10];

fstreamff("

DNF.txt"

ios:

:

in);

ff.getline(temp,10);

Alphabet=temp;

States=temp;

StartStates=temp[0];

FinalStates=temp[0];

while(!

ff.eof())

ff.getline(temp,10);

TransitionTableTemp(temp[0],temp[1],temp[2]);

/*将DNF的信息写入文件中,

第一行:

第二行:

第三行:

第四行:

以下行写入状态转换表*/

voidwrite()

out);

ff<

Alphabet<

States<

StartStates<

FinalStates<

ff<

Trans[i].present<

Trans[i].input<

Trans[i].next<

ff.close();

voidTraversal(charpresent,intN,stringstrass="

)//遍历DFA的语言集列表显示

0)

elseif(FinalStates.find(present)==FinalStates.npos&

N<

return;

intmain()

DFAexample;

example.identify();

intN;

cout<

请输入N"

cin>

N;

example.Traversal(example.StartStates,N);

example.write();

system("

pause"

);

return0;

/*测试用例

输入状态转换表

0a1

0b2

1b2

2a1

1a3

2b3

3a3

3b3

#

2b5

5b5

3b4

5a6

6b4

4a6

6a3

4b5

*/

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

当前位置:首页 > PPT模板 > 卡通动漫

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

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