NFA的实现
此次发表的是一个不确定的自动机(NFA),它可以根据输入的正规式输出由函数映像表示的结果。
此版本可以输入括号’(‘,‘)’,但是,实现的过程理解起来有点吃力,所以,在时间允许的情况下,我还将写新文章,使用单纯递归方法实现该程序。
#include"stdio.h"
#include"stdlib.h"
#define MAX 200 struct Stack
{
int Stack[MAX];
int top;
}St; struct Queue
{
int front;
int rear;
int elem[MAX];
}Q; void Input(char String[]);
void initStack(); //初始化栈
void PushStack(int x); //进栈
int PopStack(); //出栈
void initQueue();
void InserQ(int x);
int Gethead();
void decompose(char String[]);
int deal_1(char String[],int front,int rear);//处理a.b.a...
int deal_2(char String[],int front,int rear);//处理a|b|a....
int deal_3(char String[],int front,int rear);//处理a*
void cut_string(int start, int end, char String[], char temp[]); int num = ; main()
{
char String[MAX];
int i;
while(){initStack();
Input(String);
//printf("%s",String);
decompose(String);} } void Input(char String[])
{
char temp;
int i = ;
printf("请输入正规式:");
do{
temp = getchar();
//printf("%c",temp);
String[i] = temp;
i++;
}while(temp != '\n'); } void initStack()
{
St.top = -;
} void PushStack(int x)
{
St.top++;
St.Stack[St.top] = x;
}
int PopStack()
{
int temp;
temp = St.Stack[St.top];
St.top--;
return temp;
} void initQueue()
{
Q.front = Q.rear = ;
} void InserQ(int x)
{
if((Q.rear + )%MAX == Q.front)
return;
else
{
Q.elem[Q.rear] = x;
Q.rear = (Q.rear + ) % MAX;
}
} int Gethead()
{
int x;
if(Q.rear == Q.front)
printf("null\n");
else
{
x = Q.elem[Q.front];
Q.front = (Q.front+)%MAX;
}
return x;
} void decompose(char String[])
{
int flag_index = ;
char x[MAX];
int temp;
int i;
while(String[flag_index] != '\n')
{
if(String[flag_index] == '(')
{
PushStack(flag_index+);
flag_index++;
while(String[flag_index] != '\n' && St.top != -)
{
if(String[flag_index] == '(')
{
PushStack(flag_index+);
flag_index++;
}
else if(String[flag_index] == ')')
{
temp = PopStack();
flag_index++;
if(String[flag_index] == '*')
{
cut_string(temp-,flag_index,String,x);
deal_3(x,num,num);
flag_index++;
}
else
{
cut_string(temp,flag_index-,String,x);
decompose(x);
} }
else flag_index++;
}
}
for(i = flag_index ; String[i] != '\n' && String[i] != '('; i++);
if(i != flag_index)
{
// printf("1");
cut_string(flag_index,i-,String,x);
num++;
deal_2(x,num-, num); } //printf("%s",cut_string(flag_index,i - 1,String));
flag_index = i; } } int deal_1(char String[],int front,int rear)
{
int flag_index = ;
//printf("%s",String);
if(String[flag_index+] != '\n')
{
printf("f(%d, %c) = %d\n",front,String[flag_index],num);
flag_index++;
while(String[flag_index+] != '\n')
{
//printf("%c",String[flag_index]);
if(String[flag_index]>='a' && String[flag_index]<='z')
{
printf("f(%d, %c) = %d\n",num,String[flag_index],num+);
flag_index++;
num++;
}
else
flag_index++;
}
// printf("%c",String[6]);
printf("f(%d, %c) = %d\n",num,String[flag_index+],rear);
}
else
printf("f(%d, %c) = %d\n",front,String[flag_index],rear); } int deal_2(char String[],int front,int rear)
{
int flag_index = ;
int i = ;
int count = ;
char x[MAX];
int temp;
while(String[i] != '\n')
{
//printf("%c",String[flag_index]);
if(String[i] == '|')
InserQ(i++);
else i++;
}
if(Q.rear == Q.front)
{
for(i = ; String[i] != '\n'; i++)
{
if(String[i]>='a' && String[i]<='z')
count++;
}
deal_1(String,front,num + count - );
}
else
{
while(Q.rear != Q.front)
{
temp = Gethead();
cut_string(flag_index,temp-, String,x);
// printf("%d",temp);
num++;
deal_1(x, front, rear);
flag_index = temp+;
}
cut_string(flag_index,i, String,x);
deal_1(x, front, rear); }
} int deal_3(char String[],int front,int rear)
{
int flag_index = ;
int temp;
printf("f(%d, ~) = %d\n",front,++num);
temp = num;
if(String[flag_index+]==')')
{
printf("f(%d, %c) = %d\n",temp,String[],temp);
}
else
{
for(flag_index = ; String[flag_index] != '*'; flag_index++);
String[flag_index] = '\n';
decompose(String);
}
printf("f(%d, ~) = %d\n",temp,rear);
return front;
} void cut_string(int start, int end, char String[], char temp[])
{
int i;
end -= start;
for(i = ; i <= end ; i++)
{
temp[i] = String[start];
start++;
// printf("%c",temp[i]);
} temp[i] = '\n';
//printf("%d ",i);
// printf("%c",temp[i]);
}
因为时间的关系,所以代码的注释也就没有太在意,望见谅。
NFA的实现的更多相关文章
- NFA转DFA - json数字识别
json的主页上,提供了number类型的符号识别过程,如下: 图片引用:http://www.json.org/json-zh.html 实际上这张图片表示的是一个状态机,只是状态没有标出来.因为这 ...
- 求子串-KPM模式匹配-NFA/DFA
求子串 数据结构中对串的5种最小操作子集:串赋值,串比较,求串长,串连接,求子串,其他操作均可在该子集上实现 数据结构中串的模式匹配 KPM模式匹配算法 基本的模式匹配算法 //求字串subStrin ...
- NFA引擎匹配原理
1 为什么要了解引擎匹配原理 一个个音符杂乱无章的组合在一起,弹奏出的或许就是噪音,同样的音符经过作曲家的手,就可以谱出非常动听的乐曲,一个演奏者同样可以照着乐谱奏出动听的乐曲,但他/她或 ...
- 编译系统中的 NFA/DFA算法理解
1.问题概述 NFA 和 DFA浅析---要深入了解正则表达式,必须首先理解有穷自动机. 有穷自动机(Finite Automate)是用来模拟实物系统的数学模型,它包括如下五个部分: 有穷状态集St ...
- C# 词法分析器(四)构造 NFA
系列导航 (一)词法分析介绍 (二)输入缓冲和代码定位 (三)正则表达式 (四)构造 NFA (五)转换 DFA (六)构造词法分析器 (七)总结 有了上一节中得到的正则表达式,那么就可以用来构造 N ...
- nfa转dfa,正式完成
为了加速转换的处理,我压缩了符号表.具体算法参考任何一本与编译或者自动机相关的书籍. 这里的核心问题是处理传递性闭包,transitive closure,这个我目前采取的是最简单的warshall算 ...
- 正则转nfa:完成
太累了,感觉不会再爱了.问题已经解决,具体的懒得说了. #include "regular_preprocess.h" //这个版本终于要上nfa了,好兴奋啊 //由于连个节点之间 ...
- 正则转nfa:bug消除
正则到nfabug的解决方法 前面提到了这个bug,为了解决这个bug,我们必须在每次引用到一个假名的时候,都构建一个拷贝.现在假设我们遇到了一个假名,并得到了他的开始节点和结束节点,当前的难题就是构 ...
- 正则转nfa:bug出现。
本人写的一个正则到nfa的bug 刚写完前面的那篇,自己用脑子过了一下,发现了一个bug.具体情况如下. 这个bug的产生条件是多次调用假名的时候,每次调用都会修改假名的nfa图.直接这么说不好理解, ...
- 最初步的正则表达式引擎:nfa的转换规则。
[在此处输入文章标题] 正则到nfa 前言 在写代码的过程中,本来还想根据龙书上的说明来实现re到nfa的转换.可是写代码的时候发现,根据课本来会生成很多的无用过渡节点和空转换边,需要许多的代码.为了 ...
随机推荐
- Cocoapods 应用第二部分-私有库相关
我们在这里,使用的是 第一部分使用pod lib create YohunlUtilsPod 创建的framework工程来说明.其创建过程在此就不重复了,当然你也可以下载我已经创建好的demo ht ...
- eclipse导入lombok后打不开(如果你的lombok不是最新的,那就来下载最新的)
如果你的不是最新的,去这里下载最新版的,先点击左上角的Download红方块,然后再点击下图中的位置 https://projectlombok.org/ 下载完后把eclipse关掉,双击下载的ja ...
- 微信小程序开发之微信支付
微信支付是小程序开发中很重要的一个环节,下面会结合实战进行分析总结 环境准备 https服务器 微信小程序只支持https请求,因此需要配置https的单向认证服务(请参考 另一篇文章https受信证 ...
- Locust性能测试工具的安装及实际应用
一.安装Locust 安装Locust之前先安装的库:gevent库:第三方库,gevent为python提供了比较完善的协程支持.使用gevent,可以获得极高的并发性能. pip install ...
- 报错:No identifier specified for entity: main.java.com.sy.entity.User的解决办法
自己也没怎么搭建过框架,更何况还是spring mvc的,最近在带两个实习生,正好教他们怎么搭建一个spring mvc的框架,然而我在映射表的时候,提示报错了. 实体基类: public class ...
- 一次关于mongodb性能踩坑的总结
发现性能问题 上一次导入数据后,发现系统十分的卡顿,但是才仅仅1000多条数据而已,怎么会让系统变得如何的卡顿呢?于是我开始走在排查系统卡顿的原因的道路上. 首先,先定位问题是出现在前端上还是后端上. ...
- Linux - 简明Shell编程05 - 条件语句(Case)
脚本地址 https://github.com/anliven/L-Shell/tree/master/Shell-Basics 示例脚本及注释 #!/bin/bash var=$1 # 将脚本的第一 ...
- shell运算符之 关系运算符,算数运算符,布尔运算符,字符串运算符和文件测试运算符
shell运算符有很多,关系运算符,算数运算符,布尔运算符,字符串运算符和文件测试运算符 1,算术运算符 原声bash 不支持简单的算术运算,可以使用expr 工具 两点注意: 表达式和运算符之间要有 ...
- ubuntu操作系统以及开发环境的安装
网盘视频:里面包含了centos,ubuntu,Solaris 三种目前比较主流的操作系统的安装,以及他们的开发环境的安装 https://pan.baidu.com/disk/home#list/v ...
- phoenix常用命令
1.登录命令 ./sqlline.py localhost:2181:/hbase-unsecure span { font-family: "Courier New"; font ...