[编译原理代码][NFA转DFA并最小化DFA并使用DFA进行词法分析]
#include <iostream>
#include <vector>
#include <cstring>
#include "stack"
#include "algorithm"
using namespace std;
int NFAStatusNum,AlphabetNum,StatusEdgeNum,AcceptStatusNum;
char alphabet[1000];
int accept[1000];
int StartStatus;
int isDFAok=1;
int isDFA[1000][1000];
/*
* NFA状态图的邻接表
*/
vector<vector<int>> Dstates;
int Dstatesvisit[1000];
int Dtran[1000][1000];
vector<int> Dtranstart;
vector<int> Dtranend;
int isDtranstart[1000];
int isDtranend[1000];
class Edge{
public:
int to,w,next;
} ;
Edge edge[10000];
int edgetot=0;
int Graph[1000];
void link(int u,int v,int w){
edge[++edgetot].to=v;edge[edgetot].w=w;edge[edgetot].next=Graph[u];Graph[u]=edgetot;
}
void input(){
int u,v,w;
memset(Dtran,-1,sizeof(Dtran));
scanf("%d %d %d %d\n",&NFAStatusNum,&AlphabetNum,&StatusEdgeNum,&AcceptStatusNum);
for(int i=1;i<=AlphabetNum;i++){ //读入字母表
scanf("%c",&alphabet[i]);
}
for(int i=1;i<=AcceptStatusNum;i++){
scanf("%d",&accept[i]);
}
//开始状态序号
scanf("%d",&StartStatus);
for(int i=0;i<StatusEdgeNum;i++){
scanf("%d%d%d\n",&u,&v,&w);
link(u,v,w);
if(isDFA[u][v]==0){
isDFA[u][v]=1;
}
else{
isDFAok=0;
}
if(w==0){
isDFAok=0;
}
}
//读入测试字符串
}
void e_clouser(vector<int> &T,vector<int> &ans){
int visit[1000];
memset(visit,0,sizeof(visit));
stack<int> Stack;
//T all push in Stack and copy to ans
for (int i=0;i < T.size();++i){
Stack.push(T[i]);
ans.push_back(T[i]);
visit[T[i]]=1;
}
while(Stack.empty()!=1){
int t = Stack.top(); Stack.pop();
for(int p=Graph[t];p!=0;p=edge[p].next){
if(edge[p].w==0){
if(visit[edge[p].to]==0){
visit[edge[p].to]=1;
Stack.push(edge[p].to);
ans.push_back(edge[p].to);
}
}
}
}
sort(ans.begin(),ans.end());
}
void move(vector<int> &T,int a,vector<int> &ans){
int visit[1000];
memset(visit,0,sizeof(visit));
for(int i=0;i<T.size();i++) {
int t=T[i];
for (int p = Graph[t]; p != 0; p = edge[p].next) {
if (edge[p].w == a) {
if (visit[edge[p].to] == 0) {
visit[edge[p].to] = 1;
ans.push_back(edge[p].to);
}
}
}
}
}
bool notin(vector<int> &a,int &U){
for(int i=0;i<Dstates.size();i++){
int ok=1;
if(Dstates[i].size()==a.size()){
for(int j=0;j<a.size();j++){
if(Dstates[i][j]!=a[j]){
ok=0;
break;
}
}
if(ok==1) {
U=i;
return false;
}
}
}
U=Dstates.size();
return true;
}
void nfatodfa(){
vector<int> s,t;
s.push_back(StartStatus);
e_clouser(s,t);
Dstates.push_back(t);
stack<int> Stack;
Stack.push(Dstates.size()-1);
while(Stack.empty()!=1){
int T=Stack.top();Stack.pop();int U;
for(int i=1;i<=AlphabetNum;i++){
vector<int> ans,ans2;
move(Dstates[T],i,ans2);
e_clouser(ans2,ans);
if(notin(ans,U)){
Dstates.push_back(ans);
Stack.push(Dstates.size()-1);
}
Dtran[T][i]=U;
}
}
}
void getDtranStartEnd(){
for(int i=0;i<Dstates.size();i++){
int ok=1;
for(int j=0;j<Dstates[i].size();j++){
if(Dstates[i][j]==StartStatus){
Dtranstart.push_back(i);
isDtranstart[i]=1;
}
if(ok){
for(int k=1;k<=AcceptStatusNum;k++){
if(Dstates[i][j]==accept[k]){
ok=0;
Dtranend.push_back(i);
isDtranend[i]=1;
}
}
}
}
}
}
vector<vector<int>> newDstates;
int newDstatesvisit[1000];
int newDtran[1000][1000];
int set[1000];
vector<int> newDtranstart;
vector<int> newDtranend;
int isnewDtranstart[1000];
int isnewDtranend[1000];
void simple(){
int visit[1000];
memset(visit,0,sizeof(visit));
vector<int> a,b;
//接受结点加入a
for(int i=0;i<Dtranend.size();i++){
a.push_back(Dtranend[i]);
visit[Dtranend[i]]=1;
set[Dtranend[i]]=0;
}
//剩余结点加入b
for(int i=0;i<Dstates.size();i++){
if(visit[i]==0){
b.push_back(i);
set[i]=1;
}
}
newDstates.push_back(a);
newDstates.push_back(b);
while(1){
int ok=0;
for(int i=0;i<newDstates.size();i++){
for (int k = 1; k <= AlphabetNum; k++) {
for(int j=1;j<newDstates[i].size();j++) {
int pp= Dtran[newDstates[i][0]][k];
int u = newDstates[i][j], v = Dtran[u][k];
if (set[v] != set[pp] ) {
//将u剥离
newDstates[i].erase(newDstates[i].begin() + j);
vector<int> temp;
temp.push_back(u);
set[u] = newDstates.size();
newDstates.push_back(temp);
ok = 1;
break;
}
if (ok == 1) break;
}
if(ok==1) break;
}
if(ok==1) break;
}
if(ok==0) break;
}
//isnewDtranstart,isnewDtranend,newDtran
for(int i=0;i<Dstates.size();i++) {
for (int j = 1; j <= AlphabetNum; j++) {
newDtran[set[i]][j]=set[Dtran[i][j]];
}
if(isDtranend[i]==1)
isnewDtranend[set[i]]=1;
if(isDtranstart[i]==1)
isnewDtranstart[set[i]]=1;
}
//isnewDtranstart,isnewDtranend
}
bool dfa(char *S){
int index=0;
int status=0;
for(int i=0;i<newDstates.size();i++){
if(isnewDtranstart[i]==1){
status=i;
}
}
for(int i=0;i<strlen(S);i++) {
//这里我偷懒了,懒得弄个map存映射,直接对这个例子进行操作,就是 S[i]-'a'+1;
int p=S[i]-'a'+1;
status=newDtran[status][p];
}
if(isnewDtranend[status]==1) return true;
else return false;
}
int main() {
freopen("E:\\NFATODFA\\a.in","r",stdin);
input();
if(isDFAok==0){
printf("This is NFA\n");
nfatodfa();
}
else{
printf("This is DNA\n");
}
//打印DFA
printf("\nPrint DFA's Dtran:\n");
printf(" DFAstatu a b");
getDtranStartEnd();
for(int i=0;i<Dstates.size();i++){
printf("\n");
if(isDtranstart[i]==1)
printf("start ");
else if(isDtranend[i]==1)
printf("end ");
else printf(" ");
printf("%5c ",i+'A');
for(int j=1;j<=AlphabetNum;j++)
printf("%5c ",Dtran[i][j]+'A');
}
printf("\nPrint simple DFA's Dtran:\n");
simple();
printf(" DFAstatu a b");
for(int i=0;i<newDstates.size();i++){
printf("\n");
if(isnewDtranstart[i]==1)
printf("start ");
else if(isnewDtranend[i]==1)
printf("end ");
else printf(" ");
printf("%5c ",i+'A');
for(int j=1;j<=AlphabetNum;j++)
printf("%5c ",newDtran[i][j]+'A');
}
printf("\n");
char S[1000];
while(scanf("%s\n",S)!=EOF){
if(dfa(S)){
printf("%s belongs to the DFA\n",S);
}
else
printf("%s don't belong to the DFA\n",S);
}
return 0;
}
[编译原理代码][NFA转DFA并最小化DFA并使用DFA进行词法分析]的更多相关文章
- 《编译原理》构造与正规式 (0|1)*01 等价的 DFA - 例题解析
<编译原理>构造与正规式 (0|1)*01 等价的 DFA - 例题解析 解题步骤: NFA 状态转换图 子集法 DFA 的状态转换矩阵 DFA 的状态转图 解: 已给正规式:(0|1)* ...
- C#一行代码实现(01)最小化到通知区域
主要功能 实现Winform程序最小化后,隐藏任务栏显示,在通知区域显示.左键点击通知区域图标,可以弹出菜单,包含开机启动和退出程序,可以根据需求进行定制. 一行代码 private void For ...
- 编译原理实验 NFA子集法构造DFA,DFA的识别 c++11实现
实验内容 将非确定性有限状态自动机通过子集法构造确定性有限状态自动机. 实验步骤 1,读入NFA状态.注意最后需要设置终止状态. 2,初始态取空,构造DFA的l0状态,将l0加入未标记状态队列que ...
- 编译原理中DFA最小化
关于编译原理最小化的操作,专业术语请移步至:http://www.360doc.com/content/18/0601/21/11962419_758841916.shtml 这里只是记录一下个人的理 ...
- 正规式->最小化DFA说明
整体的步骤是三步: 一,先把正规式转换为NFA(非确定有穷自动机), 二,在把NFA通过"子集构造法"转化为DFA, 三,在把DFA通过"分割法"进行最小化 ...
- 自动构造词法分析器的步骤——正规式转换为最小化DFA
正规式-->最小化DFA 1.先把正则式-->NFA(非确定有穷自动机) 涉及一系列分解规则 2.再把NFA通过"子集构造法"-->DFA 通过子集构造法将NFA ...
- 最小化安装的centos7.5上编译安装git2.19
VMware Workstation已经采用最小化安装CentOS7,显示版本为CentOS7.5,准备采用yum安装git. 采用yum list git发现可安装的GIT软件包版本1.8.3.1, ...
- DFA最小化实例
原始DFA如下图所示 最小化的定义:1.没有多余的状态(死状态):2.没有两个状态是相互等价的: 两个状态等价的含义:1.兼容性(一致性)——同是终态或同是非终态:2.传播性(蔓延性)——从s出发读入 ...
- WinForm最小化到托盘以及托盘右键菜单
首先,先拖一个NotifyIcon到主窗体,然后设置NotifyIcon的图标,不然等下最小化后,都找不到那个程序了,还有那个Text也是,不写名字,就默认是NotifyIcon了..如下图: 然后双 ...
随机推荐
- nat123 与微信公众号开发者测试账号配合调试
由于公司本身是做互联网 电商行业的,微信也是一个大块,近期开始花费时间在整合,总结自己的经验,看看之前的实现是否有明显的问题. 花了点钱(8块钱)充值了nat123,进行了内网穿透.之前也有使用花生壳 ...
- bootstrap兼容IE8的一些注意
准备 bootstrap 3.3.5 jQuery 1.12.0 注意 支持html5 需要引入html5.js 支持placeholder 需要引入placeholder.js ie8 不支持 fo ...
- 关于操作DC时的资源泄露
首先应明确一个概念 句柄, 关于句柄的详细介绍请见这里 对于句柄的使用小结:借来的要归还,创建的要释放,选出的要选入[尤其是针对GDI的一些句柄而言,如HPEN,HBRUSH等] 1. 使用GetDC ...
- windows Server 2003修改远程连接限制
调整最大远程连接数: 1.开始->控制面板->添加或删除程序->添加/删除windows组件->选择“终端服务器”进行安装. 2.开始->运行->gpedit.ms ...
- php resizeimage 部分jpg文件 生成缩略图失败
今天遇到GD的resizeimage 函数处理jpg后缀文件的缩略图的时候 提示该图片不是合法的jpg图片并报错 <b>Warning</b>: imagecreatefrom ...
- 导出函数结构 EXPORT_DIRECTORY
typedef struct _IMAGE_EXPORT_DIRECTORY { DWORD Characteristics; DWORD TimeDateStamp; //输出表的创建时间 WORD ...
- Visual Studio调试之断点基础篇
Visual Studio调试之断点基础篇 我曾经问过很多人,你一般是怎么调试你的程序的? F9, F5, F11, F…… 有很多书和文章都是介绍怎么使用Visual Studio编写WinForm ...
- AudioServicesPlaySystemSound音频服务—b
对于简单的.无混音音频,AVAudio ToolBox框架提供了一个简单的C语言风格的音频服务.你可以使用AudioservicesPlaySystemSound函数来播放简单的声音.要遵守以下几个规 ...
- 『邪恶のWIFI』搭建假冒WIFI热点等女神来蹭网啊 - -。
pic by baidu 0x 00 ╮(╯▽╰)╭ 请喊我万恶的标题党 哈哈哈哈哈 0x 01 这里正题 虚拟机(Kali)不支持内置网卡,还好我有神器,插上我的RT8187L,开始搞起 参考资料 ...
- startActivityForResult案例
Info:startActivty 与 startActivityForResult区别 (1):startActivity 启动了其他Activity之后不会再回调过来,此时启动者与被启动者在启动后 ...