子集构造法实现NFA的确定化
功能: 采用子集构造算法实现NFA的确定化
输入:读取NFA的文件(文件名test.txt), 文件格式:
第一列表示状态名,第二列和第三列分别表示输入字符a和b到达的状态

输出:确定化后的DFA(文件名为output.txt),格式如下:
第一列表示输入状态名,第二列表示重新命名的状态名,第三列和第四列分别表示输入字符a和b所到达的状态

代码:
#include <stdio.h>
#include <string.h>
/* 子集构造算法实现NFA的确定化
* 输入文件:test.txt的内容
* 状态名 输字符a到达的状态 字符b到达的状态
* 0 {0,1} {0,2}
* 1 {f} {NULL}
* 2 {NULL} {f}
* f {f} {f}
* 输出文件:out.test的内容(输入状态名,字符a到达的状态,字符b到达的状态)
* {0,}ABC
* {0,2,}CBD
* {0,2,f,}DED
* {0,1,f,}EED
* {0,1,}BEC
*
*@author: finch
*@time : 2017-4-29
*/
#define num 10 //状态集合大小
#define stack_Size 10 //栈的大小
][]; //Dstates
/*
NFA信息表
*/
struct nfa_info
{
char c;
char a[num];
char b[num];
}nfa[num];
/*
DFA信息表
*/
struct dfa
{
char c[num];
char a[num];
char b[num];
}dfa[num];
/*
栈:用于实现未标记的状态的存储
可以用Dstates替代
*/
struct stack_info
{
char data[stack_Size][stack_Size];
int top;
};
typedef stack_info stack;
/*
栈的 初始化
*/
void initStack(stack *S)
{
S->top = -; // -1空栈
}
/*
栈是否为空
是: 返回 1
否: 返回 0
*/
int IsEmpty(stack *S)
{
)
{
;
}
else {
;
}
}
/*
将字符串 str入栈
*/
int push(stack *S, char str[])
{
S->top++;
if (S->top >= stack_Size)
{
printf("the stack is full\n");
;
}
strcpy(S->data[S->top], str);
printf("\n%d-%s\n", S->top, S->data[S->top]);
;
}
/*
栈顶元素出栈
赋值给str
*/
int pop(stack *S, char str[]) //出栈
{
)
{
printf("\nthe stack is empty\n");
;
}
strcpy(str, S->data[S->top]);
; i < num; i++)
{
S->data[S->top][i] = '\0';
}
S->top--;
;
}
/*
U是否在Dstates中
在:返回1
否:返回0
*/
int isBiaoji(char U[])
{
;
; Dstates[i][] != '\0';i++)
{
== strcmp(U, Dstates[i]))
state = ;
}
return state;
}
/*
是否属于NFA
*/
int isElem(char ch)
{
') || (ch >= 'A'&&ch <= 'Z'))
;
else
;
}
/*
从文件中读取数据并存到NFA中
*/
void input() //输入
{
FILE *fp_in;
fp_in = fopen("test.txt", "r");
if (fp_in == NULL)
{
printf("Error\n");
}
else {
char c;
; //行数
;
;
c = fgetc(fp_in);
while (c != EOF) //文件结束标志
{
if (c == '\n')
{
i++;
printf("\n");
j = ;
}
else if (c == '{') //遇见左括号,新的字符串
{
j++; //状态+1
index = ; //新的集合
}
)
{
) //state
{
nfa[i].c = c;
printf("C:%c\t", nfa[i].c);
}
) //经过a边到达的点
{
nfa[i].a[index] = c;
printf("A:%c\t", nfa[i].a[index]);
index++;
}
else //经过b边到达的点
{
nfa[i].b[index] = c;
printf("B:%c\t", nfa[i].b[index]);
index++;
}
}
else
{
;
}
c = fgetc(fp_in);
}
fclose(fp_in);
}
}
/*
将字符串str2中独有
的字符放到str1中
@time:2017-4-23
*/
void strcatIgnorReat(char str1[], char str2[])
{
];
; i < ;i++)
{
x[i] = '\0';
}
) //str1为空 ,直接连接
{
strcat(str1, str2);
}
else
{
strcpy(x, str2);
; str1[i] != '\0';i++)
{
; x[j] != '\0';j++)
{
if (str1[i] == x[j])
{
x[j] = '#'; //相同的用#替代
}
}
}
;i < strlen(x);i++)
{
if (x[i] != '#')
{
int index = strlen(str1);
str1[index] = x[i];
}
}
}
}
/*
状态c经过输入符号a上的转换可以到达
的NFA状态集合nfa_set
@time: 2017/4/23
@finch
*/
int move(char c, int a, char nfa_set[])
{
;
while (nfa[i].c != c && nfa[i].c != '\0') //状态c在NFA中的位置
{
i++;
}
if (nfa[i].c == c)
{
) //a边
{
!= strcmp("NULL", nfa[i].a))
{
strcatIgnorReat(nfa_set, nfa[i].a); //经过a可以到达的NFA状态集合
}
}
else {
!= strcmp("NULL", nfa[i].b)) //b边
strcatIgnorReat(nfa_set, nfa[i].b); //经过b可以到达的NFA状态集合
}
;
}
else {
;
}
}
/*
NFA确定化函数
从NFA状态Set开始可以转换
@time 2017/4/22
@finch
*/
void turn(char Set[], stack *S) //NFA确定化函数
{
; //标记数量
; //DFA下标
push(S, Set); //Set入栈
]; //每个集合经过的所有点的集合
strcpy(Dstates[bj_num], Set);
bj_num++;
== IsEmpty(S)) //栈不为空
{
char U[num]; //缓存
pop(S, U); //元素出栈
index++;
strcpy(dfa[index].c, U); //DFA
;a != ;a++) //分别对a,b边遍历
{
; i < ;i++)
{
buff[i] = '\0'; //清空
}
; U[i] != '\0'&&i < num; i++) //遍历str集合
{
move(U[i], a, buff);
}
)
{
strcpy(dfa[index].a, buff); //结合str在a边上的集合
}
else
{
strcpy(dfa[index].b, buff); //结合str在b边上的集合
}
== isBiaoji(buff))&&(strlen(buff)!=)) //新的非空集合未标记入栈并标记
{
push(S, buff);
strcpy(Dstates[bj_num], buff);
bj_num++;
}
}
}
}
/*
打印
@time 2017/4/23
*/
void print()
{
printf("\n\n");
; dfa[i].c[] != '\0';i++)
{
printf("<%s>\t\t<%s>\t\t<%s>\n", dfa[i].c, dfa[i].a, dfa[i].b);
}
}
/*
返回set在Dstates中的位置
返回 -1: 不存在
*/
int getIndex(char set[])
{
;
; Dstates[i][] != '\0';i++)
{
== strcmp(set, Dstates[i]))
state = i;
}
return state;
}
/*
输出
@time 2017/4/23
@finch
*/
void output()
{
FILE *fp_out = NULL;
if ((fp_out = fopen("output.txt", "w+")) == NULL)
{
printf("Error:can't open the file !");
}
else {
; dfa[i].c[] != '\0';i++) //重命名
{
fprintf(fp_out, "{", dfa[i].c);
; dfa[i].c[j] != '\0';j++)
{
fprintf(fp_out, "%c,", dfa[i].c[j]);
}
fprintf(fp_out, "}", dfa[i].c);
fprintf(fp_out, "%c", 'A' + getIndex(dfa[i].c));
== getIndex(dfa[i].a)) //符号a上的集合为空
{
fprintf(fp_out, "\t{%s}", "NULL");
}
else {
fprintf(fp_out, "\t%c", 'A' + getIndex(dfa[i].a));
}
== getIndex(dfa[i].b)) //符号b上的集合为空
{
fprintf(fp_out, "\t{%s}", "NULL");
}
else {
fprintf(fp_out, "\t%c", 'A' + getIndex(dfa[i].b));
}
fprintf(fp_out, "\n");
}
}
fclose(fp_out);
}
int main()
{
stack S;
initStack(&S);
input();
turn(", &S);
print();
output();
;
}
子集构造法实现NFA的确定化的更多相关文章
- 利用子集构造法实现NFA到DFA的转换
概述 NFA非有穷自动机,即当前状态识别某个转换条件后到达的后继状态不唯一,这种自动机不便机械实现,而DFA是确定有限状态的自动机,它的状态转换的条件是确定的,且状态数目往往少于NFA,所以DFA能够 ...
- 【译】N 皇后问题 – 构造法原理与证明 时间复杂度O(1)
[原] E.J.Hoffman; J.C.Loessi; R.C.Moore The Johns Hopkins University Applied Physics Laboratory *[译]* ...
- Uva 120 - Stacks of Flapjacks(构造法)
UVA - 120 Stacks of Flapjacks Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld &a ...
- [Luogu4724][模板]三维凸包(增量构造法)
1.向量点积同二维,x1y1+x2y2+x3y3.向量叉积是行列式形式,(y1z2-z1y2,z1x2-x1z2,x1y2-y1x2). 2.增量构造法: 1)首先定义,一个平面由三个点唯一确定.一个 ...
- POJ 3295 Tautology (构造法)
Tautology Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7716 Accepted: 2935 Descrip ...
- 牛客网 牛客小白月赛2 A.数字方阵-反魔方阵,梁邱构造法
天坑未补... 水一波博客,再不写博客就咸成鱼干了,只写题不写题解,过一段时间就忘了自己学过什么了. 最近重点就是把开学以来写的题补出来,没学的就滚去学会啊(= =),填一下坑... 从这篇博客开始, ...
- 紫书 习题 8-24 UVa 10366 (构造法)
又是一道非常复杂的构造法-- #include<cstdio> #include<algorithm> #define REP(i, a, b) for(int i = (a) ...
- 紫书 例题8-17 UVa 1609 (构造法)(详细注释)
这道题用构造法, 就是自己依据题目想出一种可以得到解的方法, 没有什么规律可言, 只能根据题目本身来思考. 这道题的构造法比较复杂, 不知道刘汝佳是怎么想出来的, 我想的话肯定想不到. 具体思路紫书上 ...
- LeetCode42题,单调栈、构造法、two pointers,这道Hard题的解法这么多?
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode专题的第23篇文章. 今天来看一道很有意思的题,它的难度是Hard,并且有许多种解法. 首先我们来看题面,说是我们有若 ...
随机推荐
- Linux基础命令操作实例
1.开启Linux操作系统,要求以root用户登录GNOME图形界面,语言支持选择为汉语 2.使用快捷键切换到虚拟终端2,使用普通用户身份登录,查看系统提示符 使用快捷键Ctrl+Alt+F2切换到终 ...
- Android px、dp、sp之间相互转换 系统默认12 sp
px 就是像素 sp=dpX字体比例(1.25f) 一.dp(或者dip device independent pixels) 一种基于屏幕密度的抽象单位.在每英寸160点的显示器上,1dp=1px ...
- mongodb选型问题
一.Mongodb的介绍 MongoDB 是一个跨平台的,面向文档的数据库,提供高性能,高可用性和可扩展性方便. MongoDB工作在收集和文件的概念. 数据库 数据库是一个物理容器集合.每个数据库都 ...
- JAVA发送邮件的DEMO
最近有朋友问邮件怎么发送,就简单写了个demo,因为懒得找jar包,所以项目是创建的maven工程,具体的maven引用的jar如下: <dependency> <groupId&g ...
- Python中 sys.argv[]的用法
Python中 sys.argv[]的用法 因为是看书自学的python,开始后不久就遇到了这个引入的模块函数,且一直在IDLE上编辑了后运行,试图从结果发现它的用途,然而结果一直都是没结果,也在网上 ...
- Node.js 基础介绍
什么是Node.js 官网介绍: Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. Node.js us ...
- 走入PHP-初次见面
FROM:实验楼 Linux启动WEB服务器: $ sudo service apache2 start 新建并打开test.php文件: $ sudo gvim /path/test.php PHP ...
- Python全栈开发第13天
#多用户登录 import getpass #引用getpass import os #引用os import configparser #引用配置文件操作的库 count = 0 count_oth ...
- Eclipse中将含有图片资源的项目打包成jar文件
前言: 最近学了GUI编程和UDP协议,心血来潮想做一个局域网内的聊天软件,前期都还算顺利,直到后来将整个项目打包成jar文件时遇到了困难.如图: 自己设置的图标不见了,但是也没有默认的图标,说明图片 ...
- exports和module.exports的区别
总结:exports是module.exports的指向. 1. module应该是require方法中,上下文中的对象 2. exports对象应该是上下文中引用module.exports的新对象 ...