实验二:利用子集构造法实现NFA到DFA的转换

【问题描述】利用子集构造法实现NFA到DFA的转换。NFA的确定化
【输入形式】NFA

    参见样例。其中,第一列表示状态名,终状态用f表示;第二列和第三列分别表示输入字符a和b所到达的状态。

【输出形式】DFA

    参见样例。其中,第一列表示输入状态名;第二列表示重新命名的状态名,第三列和第四列分别表示输入字符a和b所到达的状态。

【要求】

  1. 确定各个子程序的功能并画出流程图

  2. 设计子集构造算法

  3. 编码、调试通过(C/C++语言编写)

  4. 设计3-5个NFA测试实例,检验程序能否输出正确的DFA。

样例中的NFA状态转换矩阵是由下图NFA状态转换图得到

【样例输入】

0 {1} {0,1}

1 {2} {NULL}

2 {2,f} {f}

f {NULL} {NULL}

【样例输出】

{0}ABC

{1}BD

{0,1,}CEC

{2}DFG

{1,2,}EFG

{2,f,}FFG

{f}G

【样例说明】

【评分标准】与输出不一致,0分。完成正确,2分。检查通过,3分。

#include <iostream>
#include <map>
#include <string>
#include <queue>
#include <cctype>
using namespace std;
string END;
const int MAXN=100;
int Max=0;
struct Node
{string data;struct Node *next_a,*next_b;Node(){next_a=next_b=NULL;}
}G[MAXN];//建图
void Create()
{string str;int Max=0;while(getline(cin,str)){if(str.length()<1)break;int d=int(str[0]-'0');if(str[0]=='f')d=Max+1;int a=0,b=0;string str_a,str_b;str_a.clear();str_b.clear();for(int i=1;i<str.length();i++){if(str[i]=='{'&&a==0)a=i+1;else if(str[i]=='{'&&a!=0){b=i+1;break;}}int k=a;while(str[k]!='}'&&str[k]!='N'){if(!(isdigit(str[k])||str[k]=='f')){++k;continue;}str_a+=str[k];++k;}k=b;while(str[k]!='}'&&str[k]!='N'){if(!(isdigit(str[k])||str[k]=='f')){++k;continue;}str_b+=str[k];++k;}Node* p=&G[d];for(int i=0;i<str_a.length();i++){if(isdigit(str_a[i])&&int(str_a[i]-'0')>Max)Max=int(str_a[i]-'0');while(p->next_a!=NULL)p=p->next_a;p->next_a=new Node;p=p->next_a;p->data=str_a[i];}p=&G[d];for(int i=0;i<str_b.length();i++){if(isdigit(str_b[i])&&int(str_b[i]-'0')>Max)Max=int(str_b[i]-'0');while(p->next_b!=NULL)p=p->next_b;p->next_b=new Node;p=p->next_b;p->data=str_b[i];}}Max++;for(int i=0;i<=Max;i++)  //替换掉所有的f{Node* p=G[i].next_a;while(p!=NULL){if(p->data=="f")p->data='0'+Max;p=p->next_a;}p=G[i].next_b;while(p!=NULL){if(p->data=="f")p->data='0'+Max;p=p->next_b;}}END+='0'+Max;
}
//输出首元素
void output(string str)
{cout<<"{";if(str.length()==1){char c='0'+str[0]-'0';if(str[0]!=END[0])cout<<c<<"}";else cout<<"f"<<"}";}else{for(int i=0;i<str.length();i++){if(str[i]!=END[0])cout<<str[i]<<",";else cout<<"f,";}cout<<"}";}
}
//获取后继状态,k==0是找输入a的,否则是b的
string get_next(Node* p,int k=0)
{string str;str.clear();Node* t=p;while(t!=NULL){str+=t->data;if(!k)t=t->next_a;else t=t->next_b;}return str;
}
//删除重复元素
void Del(string &str)
{string::iterator it=str.begin();for(;it!=str.end();it++){for(string::iterator it1=it+1;it1<=str.end()-1;it1++){if(*it1==*it)str.erase(it1);}}
}
//输出最终状态
void print()
{queue<string>Q;map<string,int>M,M1; //M是输出不重复,M1是用于添加总的M1["0"]=0;Q.push("0");int cur=0;while(!Q.empty())//&&Q.front()!=END){string tmp=Q.front();Q.pop();map<string,int>::iterator it=M.find(tmp);if(it!=M.end())continue;  //不输出重复的M.insert(pair<string,int>(tmp,M.size()+1));output(tmp);  //输出出发结点char c='A'+M.size()-1;cout<<c;string str_a,str_b;  //a存储输入a后的结论,b同理str_a.clear();str_b.clear();for(int i=0;i<tmp.length();i++){int d=int(tmp[i]-'0');str_a+=get_next(G[d].next_a,0);str_b+=get_next(G[d].next_b,1);Del(str_a);  //删除重复元素Del(str_b);}c='\0';  //初始化清空一次it=M1.find(str_a);if(str_a.length()>0&&it==M1.end())  //如果没在集合内部{cur++;c='A'+cur;M1.insert(pair<string,int>(str_a,cur));}else if(str_a.length()>0)c='A'+M1.find(str_a)->second;cout<<c;  //输出 输入a后的结果if(str_a.length()>0)Q.push(str_a);c='\0'; //初始化清空一次it=M1.find(str_b);if(str_b.length()>0&&it==M1.end()){cur++;M1.insert(pair<string,int>(str_b,cur));c='A'+cur;}else if(str_b.length()>0)c='A'+M1.find(str_b)->second;if(str_b.length()>0)Q.push(str_b);cout<<c<<endl;  //输出 输入b后的结果}
}int main()
{Create();print();
}/*
0 {0,1} {0,2}
1 {f} {NULL}
2 {NULL} {f}
f {f} {f}
*/

NFA转DFA程序设计相关推荐

  1. 词法分析(NFA与DFA)

    词法分析(1)---词法分析的有关概念以及转换图 词法分析是编译的第一个阶段,前面简介中也谈到过词法分析器的任务就是: 字符流------>词法记号流 这里词法分析和语法分析会交错进行,也就是说 ...

  2. NTU 课程辅助笔记: NFA到DFA的转化

    我们以这张图为例: 用 Finite State Machine Designer - by Evan Wallace (madebyevan.com) 画的,有几条边的mark没画好错位了 1 写出 ...

  3. 词法分析(4)---NFA与DFA的转化

    1. 子集构造(Subset Construction) 这是一个转换NFA到DFA的算法.我们知道NFA和DFA的区别最主要的就是一个状态和一个input symbol是否能够确定一个状态的问题,对 ...

  4. nfa状态转换图正规式_0x02 从NFA到DFA

    书接上文,上回说道NFA已经可以完全描述正则语言的全部内容.那么,我们在这一章探索一下一个比较复杂的正则表达式在用NFA做匹配的时候会有什么"不足". NFA匹配的"不足 ...

  5. python 求子字符串_求子串-KPM模式匹配-NFA/DFA

    求子串 数据结构中对串的5种最小操作子集:串赋值,串比较,求串长,串连接,求子串,其他操作均可在该子集上实现 数据结构中串的模式匹配 KPM模式匹配算法 基本的模式匹配算法 //求字串subStrin ...

  6. 编译原理: Subset Construction 子集构造法(幂集构造)(NFA转DFA)

    编译原理: Subset Construction 子集构造法(幂集构造)(NFA转DFA) 文章目录 编译原理: Subset Construction 子集构造法(幂集构造)(NFA转DFA) 简 ...

  7. 利用子集构造法实现NFA到DFA的转换

    概述 NFA非有穷自动机,即当前状态识别某个转换条件后到达的后继状态不唯一,这种自动机不便机械实现,而DFA是确定有限状态的自动机,它的状态转换的条件是确定的,且状态数目往往少于NFA,所以DFA能够 ...

  8. NFA到DFA的子集构造法

    摘录博客:https://blog.csdn.net/qq_23100787/article/details/50402643 整体的步骤是三步:  一,先把正规式转换为NFA(非确定有穷自动机),  ...

  9. 编译原理——实现NFA到DFA 的转换(子集构造法)

    一.实验内容 利用⼦集构造法的实现任意NFA到DFA 的转换. 二.编程思路: 建立一个NFA类,包括初始状态,输入,下一状态: 建立一个DFA类,包括初始状态,输入,下一状态: 建立init()函数 ...

最新文章

  1. SAP PM入门系列32 - S_ALR_87013432 Display Confirmations
  2. 湘潭大学网络编程_湘潭大学计算机学院网络空间安全学院“湘韵”研究生论坛成功举行...
  3. 在ASP.NET中上传图片并生成缩略图
  4. 开源声码器WORLD在语音合成中的应用
  5. 英语常见介词错误用法,你有犯过吗?
  6. 各种Java加密算法
  7. 打开一个页面,并监听该页面的关闭事件
  8. 具有Ubuntu和Azure Data Studio的Linux上SQL Server 2019
  9. python编写交互界面查分_python小习题:查分数 - 李金龙
  10. [Java] 蓝桥杯BASIC-28 基础练习 Huffuman树
  11. C++获取文本文件字节数的一个小方法
  12. 简单高效,分享几款我在使用的效率神器
  13. Spring Boot内嵌的tomcat日志
  14. 即时通信软件实现原理
  15. Linux的磁盘分区、基本目录结构
  16. @Resource报错
  17. 高考数学解题技巧:基本不等式求最值神奇方法-神奇设k法
  18. 如何设计空白页面,体验更好!
  19. 微信公众号开发__微信网页授权并获取用户基本信息(是否关注公众号、头像、昵称等)
  20. 关于win10安装PingFangThin字体后换不回来的问题

热门文章

  1. java heap 查看_使用VisualVM查看Java Heap Dump
  2. 【机器学习-西瓜书】三、线性回归;对数线性回归
  3. LeetCode 59. 螺旋矩阵 II(python、c++)
  4. AcWing 1056. 股票买卖 III
  5. 机器学习 Machine Learning中向量化矩阵化的技巧
  6. Burpsuite工具的代理抓包功能实验
  7. python配置文件转dict
  8. 移植ubuntu14.04根文件系统至beaglebone开发板探索
  9. 补充“为什么Scrum不行”
  10. 【编程珠玑】第十章 节省空间