这个是最基础的解释器,它实现了串联、并联、克林闭包,字符集为除了()|*的ASCII字符,而且不能判断表达式合法,效率还很低,内存利用率低。

它只能判读输入的字符串是否符合表达式。

#include<bits/stdc++.h>
using namespace std;
namespace GDRegex
{
const int EPSILON=-;
const int ISEND=-;
const int MAXN=<<;
struct Node;
struct Edge;
struct Fa;
int TI,c1[MAXN],c2[MAXN];
struct Edge
{
Edge*next;
Node*to;
int w;
};
struct Node
{
Edge*head,*tail;
int num;
Node()
{
num=++TI;
head=new Edge;
head->w=ISEND;
tail=head;
}
inline void add(Node*v,int w)
{
assert(w!=ISEND);
tail->to=v;
tail->w=w;
tail->next=new Edge;
tail=tail->next;
tail->w=ISEND;
}
}*wait1[MAXN],*wait2[MAXN];
struct FA
{
Node*start,*end;
int endPos;
FA()
{
start=new Node();
end=new Node();
start->add(end,EPSILON);
endPos=end->num;
};
FA(int ch)
{
start=new Node();
end=new Node();
start->add(end,ch);
endPos=end->num;
}
FA(string str)
{
start=new Node();
end=new Node();
Node*p=start;
for(int i=;i<str.size();++i)
{
Node*x=new Node;
p->add(x,str[i]);
p=x;
}
p->add(end,EPSILON);
endPos=end->num;
}
bool match(string str)
{
int tot=;
map<pair<int,int>,bool>vis;
int len1=,len2=,len=str.size();
c1[len1]=;
wait1[len1++]=start;
vis[make_pair(,start->num)]=;
while(len1)
{
len2=;
for(int i=;i<len1;++i)
{
Node*u=wait1[i];
for(Edge*e=u->head;e->w!=ISEND;e=e->next)
{
Node*v=e->to;
// cout<<"NOW "<<u->num<<" "<<v->num<<" "<<(char)e->w<<" "<<str[c1[i]]<<" "<<c1[i]<<endl;
++tot;
if(e->w==EPSILON)
{
if(c1[i]==len&&v->num==endPos)
return true;
if(vis[make_pair(v->num,c1[i])])
continue;
c2[len2]=c1[i];
wait2[len2]=v;
vis[make_pair(v->num,c2[len2++])]=;
}
else if(e->w==str[c1[i]]&&!vis[make_pair(v->num,c1[i]+)])
{
if(c1[i]+==len&&v->num==endPos)
return true;
if(c1[i]+>len)
continue;
c2[len2]=c1[i]+;
wait2[len2]=v;
vis[make_pair(v->num,c2[len2++])]=;
}
}
}
for(int i=;i<max(len1,len2);++i)
swap(wait1[i],wait2[i]),swap(c1[i],c2[i]);
swap(len1,len2);
}
return false;
}
};
FA getSeries(const FA&A,const FA&B)
{
FA C=A;
C.end->add(B.start,EPSILON);
C.end=B.end;
C.endPos=B.endPos;
return C;
}
FA getParallel(const FA&A,const FA&B)
{
FA C,D=A,E=B;
C.end->add(D.start,EPSILON);
C.end->add(E.start,EPSILON);
D.end->add(E.end,EPSILON);
C.end=E.end;
C.endPos=E.endPos;
return C;
}
FA getKleene(const FA&A)
{
FA B,C=A;
B.start->add(C.start,EPSILON);
C.end->add(B.start,EPSILON);
return B;
}
FA getFA(string str)
{
stack<pair<FA,int> >S;
for(int i=;i<str.size();++i)
{
if(str[i]=='(')
S.push(make_pair(FA(),));
else if(str[i]==')')
{
pair<FA,int>A=S.top();
S.pop();
while(!S.empty())
{
pair<FA,int>B=S.top();
if(B.second==)
break;
else if(B.second==)
A.first=getSeries(B.first,A.first);
else if(B.second==)
A.first=getParallel(B.first,A.first);
S.pop();
}
A.second=;
S.push(A);
}
else if(str[i]=='*')
{
pair<FA,int>A=S.top();
S.pop();
A.first=getKleene(A.first);
A.second=;
S.push(A);
}
else if(str[i]=='|')
{
pair<FA,int>A=S.top();
S.pop();
while(!S.empty())
{
pair<FA,int>B=S.top();
if(B.second==||B.second==)
break;
A.first=getSeries(B.first,A.first);
S.pop();
}
A.second=;
S.push(A);
}
else
S.push(make_pair(FA(str[i]),));
}
FA A;
while(!S.empty())
{
pair<FA,int>B=S.top();
S.pop();
if(B.second==)
A=getSeries(B.first,A);
else if(B.second==)
A=getParallel(B.first,A);
}
return A;
}
}
int main()
{
ios::sync_with_stdio(false);
using namespace GDRegex;
FA A=getFA("(0|1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)");
while(true)
{
string str;
cin>>str;
cout<<A.match(str)<<endl;
}
return ;
}

2020_02_01

正则表达式在c++中的实现的更多相关文章

  1. 正则表达式在iOS中的运用

    1.什么是正则表达式 正则表达式,又称正规表示法,是对字符串操作的一种逻辑公式.正则表达式可以检测给定的字符串是否符合我们定义的逻辑,也可以从字符串中获取我们想要的特定部分.它可以迅速地用极简单的方式 ...

  2. 正则表达式(/[^0-9]/g,'')中的"/g"是什么意思?

    解答“正则表达式(/[^0-9]/g,'')中的"/g"是什么意思?”这个问题,也为了能够便于大家对正则表达式有一个更为综合和深刻的认识,我将一些关键点和容易犯糊涂的地方再系统总结 ...

  3. 正则表达式(/[^0-9]/g,'')中的"/g"是什么意思 ?

    正则表达式(/[^0-9]/g,'')中的"/g"是什么意思 ?     表达式加上参数g之后,表明可以进行全局匹配,注意这里“可以”的含义.我们详细叙述: 1)对于表达式对象的e ...

  4. JS正则表达式获取字符串中特定字符

    JS正则表达式获取字符串中得特定字符,通过replace的回调函数获取. 实现的效果:在字符串中abcdefgname='test'sddfhskshjsfsjdfps中获取name的值test  实 ...

  5. C#用正则表达式去掉Html中的script脚本和html标签

    原文 C#用正则表达式去掉Html中的script脚本和html标签 /// <summary>         /// 用正则表达式去掉Html中的script脚本和html标签     ...

  6. java正则表达式提取地址中的ip和端口号

    由于我需要用到java正则表达式提取地址中的ip和端口号,所以我就写了一个demo,测试一下,下面是demo public class Test0810_1 { public static void ...

  7. 使用Dreamweaver正则表达式替换href中的内容

    在Dreamweaver中使用正则表达式替换href中的内容,就像下面这些href中的内容复杂多样的情况下,href="/html/u.html",href="/tuho ...

  8. 正则表达式在Java中的使用

    目录 介绍 从简单例子认识正则表达式匹配 Java中对正则表达式的支持(各种语言有相应的实现) 初步认识 . + * ? 范围 认识\s \w \d - 下面介绍数字和字母的正则表达, 这是编程中使用 ...

  9. 正则表达式与Python中re模块的使用

    正则表达式与Python中re模块的使用 最近做了点爬虫,正则表达式使用的非常多,用Python做的话会用到re模块. 本文总结一下正则表达式与re模块的基础与使用. 另外,给大家介绍一个在线测试正则 ...

  10. 正则表达式在JS中的使用

    <script type="text/javascript"> /** *正则表达式在js中的第一种使用方式: * RegExp 通过构造器去使用正则表达式 需要对反斜 ...

随机推荐

  1. 第二阶段:2.商业需求分析及BRD:5.商业需求文档1

    三大文档 FSD一般包含在PRD 1.BRD一般是去向决策层汇报 2.产品介绍的各项是可选的 不是必备的 产品线路图就是roodmap.团队一般是偏技术的团队. BRD案例. 痛点.定性的描述.不会非 ...

  2. 超简单!pytorch入门教程(二):Autograd

    一.autograd自动微分 autograd是专门为了BP算法设计的,所以这autograd只对输出值为标量的有用,因为损失函数的输出是一个标量.如果y是一个向量,那么backward()函数就会失 ...

  3. Raid相关操作与注意事项记录

    Raid相关操作与注意事项 Raid5 SATA盘组成的Raid5,在保护数据的前提下达到高性能: RAID要有BBU Current Cache Policy采用WriteBack,No Write ...

  4. Linux(Centos)安装node及anyproxy

    一.安装node //下载 wget https://nodejs.org/dist/v10.9.0/node-v10.9.0-linux-x64.tar.xz //解压 tar xf node-v1 ...

  5. 快速部署 Spring PetClinic 到函数计算平台

    简介 首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute):函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传.函数计算准 ...

  6. 如何在Linux上创建,列出和删除Docker容器

    本篇文章介绍的内容是关于在Linux机器上创建,列出和删除docker容器,下面我们来看具体的内容. 1.启动Docker容器 使用下面的命令启动新的Docker容器.这将启动一个新的容器,并为你提供 ...

  7. 1043 输出PATest (20 分)C语言

    给定一个长度不超过 10^​4的.仅由英文字母构成的字符串.请将字符重新调整顺序,按 PATestPATest- 这样的顺序输出,并忽略其它字符.当然,六种字符的个数不一定是一样多的,若某种字符已经输 ...

  8. docker-bind挂载

    使用绑定挂载 自Docker早期以来,绑定挂载一直存在.与卷相比,绑定装载具有有限的功能.使用绑定装入时,主机上的文件或目录将装入容器中.文件或目录由其在主机上的完整路径或相对路径引用.相反,当您使用 ...

  9. zTree 节点勾选取消勾选 选中取消选中

    zTreeObj.cancelSelectedNode function 举例 取消当前所有被选中节点的选中状态 var treeObj = $.fn.zTree.getZTreeObj(" ...

  10. Linux 学习笔记 6 搭建nginx 实现二级域名访问

    前言 在前一节的内容里面,我们学习了如何使用yum 包管理工具来安装我们需要的软件,这节内容,通过搭建Nginx 反向代理服务器,以及学习服务的配置等内容. NGINX Nginx是一款轻量级的Web ...