DFA Minimization
有点晚了我就不调试了..不过说是这么说我还是过了编译的..
#include<bits/stdc++.h>
using namespace std;
namespace DFA{
const int alp=10;
struct Node{int t[alp],a;Node(){}Node(int tx,int ac):a(ac){for(int i=0;i<alp;++i)t[i]=tx;}};
struct DFA{
vector<Node>nodes;
int starting;
int crt(int ac=0){nodes.emplace_back(nodes.size(),ac);}
void ss(int s){starting=s;}
void st(int s,int c,int t){nodes[s].t[c]=t;}
void sa(int s,int a){nodes[s].a=a;}
};
int _C_u_dd(vector<int>&a,const DFA&tt,int pos,int up){
a[pos]=up++;
const Node&g=tt.nodes[pos];
for(int i=0;i<alp;++i)if(!a[g.t[i]])
up=_C_u_dd(a,tt,g.t[i],up);
return up;
}
int Cut_unreachable(DFA&cc,const DFA&tt){
cc.nodes.clear();
vector<int>z;
z.resize(tt.nodes.size());
int gr=_C_u_dd(z,tt,tt.starting,1);
cc.nodes.resize(gr);
for(int i=0,_=tt.nodes.size();i<_;++i)if(z[i]){
const Node&p=tt.nodes[i];
Node&q=cc.nodes[z[i]];
q.a=p.a;
for(int i=0;i<alp;++i)
q.t[i]=z[p.t[i]];
}cc.ss(1);
return gr-1;
}
namespace PRS{
struct q{
vector<int>son;int tid,in;
q(int sz=0):tid(-1){if(sz)son.resize(sz);}
};
typedef pair<int,int>o;
struct p{
vector<q>z;
vector<o>b;
p(int t){
z.emplace_back(t);
b.resize(t+1);
for(int i=0;i<t;++i)
b[i+1]=o(0,i),z[0].son[i]=i+1;
}
void _reassign(q&a,int s){
q&t=z[a.tid];
int id=a.son[s];
if(s!=a.son.size()-1){
int idr=a.son[a.son.size()-1];
b[idr].second=s;
swap(a.son[s],a.son[a.son.size()-1]);
}a.son.pop_back();
b[id]=o(a.tid,t.son.size());
t.son.push_back(id);
}
vector<o>split(vector<int>t){
vector<o>q;
for(int v:t){
if(z[b[v].first].tid==-1){
q.emplace_back(b[v].first,z.size());
z[b[v].first].tid=z.size(),z.emplace_back();
}_reassign(z[b[v].first],b[v].second);
}for(o g:q)
z[g.first].tid=-1;
return q;
}
};
}
typedef vector<int> inlist[alp];
void DFA_Minimize(DFA&tt){
DFA gg;
int si=Cut_unreachable(gg,tt);
PRS::p pr(si);
vector<int>vi;
inlist*inl=new inlist[si+1];
for(int i=1;i<=si;++i){
for(int j=0;j<alp;++j)
inl[gg.nodes[i].t[j]][j].push_back(i);
if(gg.nodes[i].a)
vi.push_back(i);
}auto gd=pr.split(vi)[0];
stack<int>sets;
sets.push(gd.second);
pr.z[gd.second].in=1;
while(!sets.empty()){
int setNow=sets.top();sets.pop();
pr.z[setNow].in=0;
vector<int>qs;
for(int i:pr.z[setNow].son)
qs.push_back(i);
for(int j=0;j<alp;++j){
vi.clear();
for(int i:qs)
for(int k:inl[i][j])
vi.push_back(k);
auto qt=pr.split(vi);
for(auto i:qt)
if(pr.z[i.first ].son.size()&&
pr.z[i.second].son.size())
if(pr.z[i.first ].in||
pr.z[i.first ].son.size()>
pr.z[i.second].son.size())
sets.push(i.second),pr.z[i.second].in=1;
else sets.push(i.first),pr.z[i.first].in=1;
}
}int id=1;
for(auto i:pr.z)if(i.son.size())
i.in=id++;
tt.nodes.resize(id);
for(auto i:pr.z)if(i.son.size()){
Node&q=tt.nodes[i.in];
Node&u=gg.nodes[i.son[0]];
for(int j=0;j<alp;++j)
q.t[j]=pr.z[pr.b[u.t[j]].first].in;
}tt.starting=pr.z[pr.b[1].first].in;
delete[]inl;
}
}
int main(){
return 0;
}
最后祝您身体健康,再见.
DFA Minimization的更多相关文章
- 基于DFA敏感词查询的算法简析
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 项目中需要对敏感词做一个过滤,首先有几个方案可以选择: a.直 ...
- java实现敏感词过滤(DFA算法)
小Alan在最近的开发中遇到了敏感词过滤,便去网上查阅了很多敏感词过滤的资料,在这里也和大家分享一下自己的理解. 敏感词过滤应该是不用给大家过多的解释吧?讲白了就是你在项目中输入某些字(比如输入xxo ...
- 使用DFA做文本编辑器的自动提示
之前看龙书的时候,龙书提到可以在编译器里用动态的生成的NFA自动机来动态匹配自己的输入串,NFA的简单实现其实写起来非常简单,但是我是实际凭感觉写完之后,却觉得并不是非常的好用,在处理自己已经输入过的 ...
- DFA 最小化
NDFA.εNDFA 确定化的细节这里就不总结了,这里说一说DFA最小化的算法. 关于DFA最小化,
- C# 词法分析器(五)转换 DFA
系列导航 (一)词法分析介绍 (二)输入缓冲和代码定位 (三)正则表达式 (四)构造 NFA (五)转换 DFA (六)构造词法分析器 (七)总结 在上一篇文章中,已经得到了与正则表达式等价的 NFA ...
- NFA转DFA - json数字识别
json的主页上,提供了number类型的符号识别过程,如下: 图片引用:http://www.json.org/json-zh.html 实际上这张图片表示的是一个状态机,只是状态没有标出来.因为这 ...
- DFA敏感词过滤
import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import java.util.ArrayList; ...
- 求子串-KPM模式匹配-NFA/DFA
求子串 数据结构中对串的5种最小操作子集:串赋值,串比较,求串长,串连接,求子串,其他操作均可在该子集上实现 数据结构中串的模式匹配 KPM模式匹配算法 基本的模式匹配算法 //求字串subStrin ...
- 编译系统中的 NFA/DFA算法理解
1.问题概述 NFA 和 DFA浅析---要深入了解正则表达式,必须首先理解有穷自动机. 有穷自动机(Finite Automate)是用来模拟实物系统的数学模型,它包括如下五个部分: 有穷状态集St ...
随机推荐
- Nginx学习记录(二)
1. 什么是反向代理 正向代理 反向代理: 反向代理服务器决定哪台服务器提供服务. 返回代理服务器不提供服务器.也是请求的转发. 反向代理(Reverse Proxy)方式是指以代理服务器来接受Int ...
- 重载&重写
重载:同一个类中,方法名相同,方法参数不同(参数个数.参数类型),返回类型无关,所以返回类型不能作为重载的区别依据. 重写:子父类中,子类的方法名.参数位置.参数个数.返回类型和父类一致,方法体不同 ...
- python之2.x与3.x区别(仅限于基础)
因为看的是python2.x的书籍.用的是python 3.7.所以先把两者的区别记录一下,仅限于基础. 1.input python3.0之后,不区分input()和raw_input(),统一为i ...
- h5获取摄像头拍照功能
完整代码展示 <!DOCTYPE html> <head> <title>HTML5 GetUserMedia Demo</title> <met ...
- JZOJ 5456. 【NOIP2017提高A组冲刺11.6】奇怪的队列
5456. [NOIP2017提高A组冲刺11.6]奇怪的队列 (File IO): input:queue.in output:queue.out Time Limits: 1000 ms Mem ...
- python-01 spider原理
用Python可以做什么?可以做日常任务,比如自动备份你的MP3:可以做网站,很多著名的网站包括YouTube就是Python写的:可以做网络游戏的后台,很多在线游戏的后台都是Python开发的.总之 ...
- Tomcat之web.xml中的<url-pattern>标签
关于web.xml配置中的<url-pattern> 标签<url-pattern> <url-pattern>是我们用Servlet做Web项目时需要经常配置的标 ...
- HBase官方文档
HBase官方文档 目录 序 1. 入门 1.1. 介绍 1.2. 快速开始 2. Apache HBase (TM)配置 2.1. 基础条件 2.2. HBase 运行模式: 独立和分布式 2.3. ...
- jmeter非GUI模式如何压测并生成测试报告
在启动Jmeter时,我们会看到这样一句提示: 不要使用GUI模式(界面模式)进行负载测试,GUI模式只能用于创建测试和调试.进行负载测试时,需要时用非GUI模式. 那么为什么进行负载测试时一定要用非 ...
- python-生成器迭代器及递归调用
生成器是一个可迭代的对象,它的执行会记住上一次返回时在函数体中的位置.对生成器第二次(或第 n 次)调用跳转至该函数上次执行位置继续往下执行,而上次调用的所有局部变量都保持不变. 生成器的特点:1.生 ...