#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进行词法分析]的更多相关文章

  1. 《编译原理》构造与正规式 (0|1)*01 等价的 DFA - 例题解析

    <编译原理>构造与正规式 (0|1)*01 等价的 DFA - 例题解析 解题步骤: NFA 状态转换图 子集法 DFA 的状态转换矩阵 DFA 的状态转图 解: 已给正规式:(0|1)* ...

  2. C#一行代码实现(01)最小化到通知区域

    主要功能 实现Winform程序最小化后,隐藏任务栏显示,在通知区域显示.左键点击通知区域图标,可以弹出菜单,包含开机启动和退出程序,可以根据需求进行定制. 一行代码 private void For ...

  3. 编译原理实验 NFA子集法构造DFA,DFA的识别 c++11实现

    实验内容 将非确定性有限状态自动机通过子集法构造确定性有限状态自动机. 实验步骤 1,读入NFA状态.注意最后需要设置终止状态. 2,初始态取空,构造DFA的l0状态,将l0加入未标记状态队列que ...

  4. 编译原理中DFA最小化

    关于编译原理最小化的操作,专业术语请移步至:http://www.360doc.com/content/18/0601/21/11962419_758841916.shtml 这里只是记录一下个人的理 ...

  5. 正规式->最小化DFA说明

      整体的步骤是三步: 一,先把正规式转换为NFA(非确定有穷自动机), 二,在把NFA通过"子集构造法"转化为DFA, 三,在把DFA通过"分割法"进行最小化 ...

  6. 自动构造词法分析器的步骤——正规式转换为最小化DFA

    正规式-->最小化DFA 1.先把正则式-->NFA(非确定有穷自动机) 涉及一系列分解规则 2.再把NFA通过"子集构造法"-->DFA 通过子集构造法将NFA ...

  7. 最小化安装的centos7.5上编译安装git2.19

    VMware Workstation已经采用最小化安装CentOS7,显示版本为CentOS7.5,准备采用yum安装git. 采用yum list git发现可安装的GIT软件包版本1.8.3.1, ...

  8. DFA最小化实例

    原始DFA如下图所示 最小化的定义:1.没有多余的状态(死状态):2.没有两个状态是相互等价的: 两个状态等价的含义:1.兼容性(一致性)——同是终态或同是非终态:2.传播性(蔓延性)——从s出发读入 ...

  9. WinForm最小化到托盘以及托盘右键菜单

    首先,先拖一个NotifyIcon到主窗体,然后设置NotifyIcon的图标,不然等下最小化后,都找不到那个程序了,还有那个Text也是,不写名字,就默认是NotifyIcon了..如下图: 然后双 ...

随机推荐

  1. Windows7电脑上不去网,ipconfig查询时默认网关会出现0.0.0.0问题的解决

    用ipconfig查看网络配置,发现其他都正确,唯独默认网关上多了一条0.0.0.0的记录,.禁用网络连接再启用也不能恢复.网上找了一下有说改注册表的,打开注册表找到 HKEY_LOCAL_MACHI ...

  2. JQuery 解析xml

    JQuery 可以通过 $.get() 或 $.post() 方法来加载 xml.     JQuery 解析 XML 与解析 DOM 一样, 可以使用 find(), children() 等函数来 ...

  3. 武汉科技大学ACM:1008: 零起点学算法64——回型矩阵

    Problem Description 输出n*m的回型矩阵 Input 多组测试数据 每组输入2个整数 n和m(不大于20) Output 输出n*m的回型矩阵,要求左上角元素是1,(每个元素占2个 ...

  4. poj2236 基础并查集

    题目链接:http://poj.org/problem?id=2236 题目大意:城市网络由n台电脑组成,因地震全部瘫痪,现在进行修复,规定距离小于等于d的电脑修复之后是可以直接相连 进行若干操作,O ...

  5. 拿起cl.exe,放下IDE

    笔者在这里介绍一种使用cl.exe编译源文件的方法,可以手动执行编译过程而不再依赖IDE,此外,笔者还介绍一些使用cl.exe编译简单源代码的方式. cl.exe是windows平台下的编译连接程序, ...

  6. phpcms V9 修改生成静态文件路径/html

    在论坛看到部分用户反馈这个问题,要修改的其实是html_root的值,默认是"/html"如果要生成在网站根目录的话,这个值则要为空.论坛上现在看到的办法是打开caches\con ...

  7. Python3 如何优雅地使用正则表达式(详解六)

    修改字符串 我们已经介绍完如何对字符进行搜索,接下来我们讲讲正则表达式如何修改字符串. 正则表达式使用以下方法修改字符串: 方法 用途 split() 在正则表达式匹配的地方进行分割,并返回一个列表 ...

  8. C语言编程的进制问题问题

    在我们的编译器,我用的是ADS   开发平台,现在RTC模块编程时,2410作为上位机,如下代码: n = rBCDDATE;if(n==1) time->day =0x31 ; 波斯历的日期与 ...

  9. Android 把从网络获取的图片缓存到内存中

    1:activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/androi ...

  10. MySQL原生HA方案 – Fabric体验之旅

    http://www.csdn.net/article/2014-08-20/2821300