正则表达式在c++中的实现
这个是最基础的解释器,它实现了串联、并联、克林闭包,字符集为除了()|*的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++中的实现的更多相关文章
- 正则表达式在iOS中的运用
1.什么是正则表达式 正则表达式,又称正规表示法,是对字符串操作的一种逻辑公式.正则表达式可以检测给定的字符串是否符合我们定义的逻辑,也可以从字符串中获取我们想要的特定部分.它可以迅速地用极简单的方式 ...
- 正则表达式(/[^0-9]/g,'')中的"/g"是什么意思?
解答“正则表达式(/[^0-9]/g,'')中的"/g"是什么意思?”这个问题,也为了能够便于大家对正则表达式有一个更为综合和深刻的认识,我将一些关键点和容易犯糊涂的地方再系统总结 ...
- 正则表达式(/[^0-9]/g,'')中的"/g"是什么意思 ?
正则表达式(/[^0-9]/g,'')中的"/g"是什么意思 ? 表达式加上参数g之后,表明可以进行全局匹配,注意这里“可以”的含义.我们详细叙述: 1)对于表达式对象的e ...
- JS正则表达式获取字符串中特定字符
JS正则表达式获取字符串中得特定字符,通过replace的回调函数获取. 实现的效果:在字符串中abcdefgname='test'sddfhskshjsfsjdfps中获取name的值test 实 ...
- C#用正则表达式去掉Html中的script脚本和html标签
原文 C#用正则表达式去掉Html中的script脚本和html标签 /// <summary> /// 用正则表达式去掉Html中的script脚本和html标签 ...
- java正则表达式提取地址中的ip和端口号
由于我需要用到java正则表达式提取地址中的ip和端口号,所以我就写了一个demo,测试一下,下面是demo public class Test0810_1 { public static void ...
- 使用Dreamweaver正则表达式替换href中的内容
在Dreamweaver中使用正则表达式替换href中的内容,就像下面这些href中的内容复杂多样的情况下,href="/html/u.html",href="/tuho ...
- 正则表达式在Java中的使用
目录 介绍 从简单例子认识正则表达式匹配 Java中对正则表达式的支持(各种语言有相应的实现) 初步认识 . + * ? 范围 认识\s \w \d - 下面介绍数字和字母的正则表达, 这是编程中使用 ...
- 正则表达式与Python中re模块的使用
正则表达式与Python中re模块的使用 最近做了点爬虫,正则表达式使用的非常多,用Python做的话会用到re模块. 本文总结一下正则表达式与re模块的基础与使用. 另外,给大家介绍一个在线测试正则 ...
- 正则表达式在JS中的使用
<script type="text/javascript"> /** *正则表达式在js中的第一种使用方式: * RegExp 通过构造器去使用正则表达式 需要对反斜 ...
随机推荐
- Servlet学习笔记(一)
使用Servlet所需要导入的包: java.io.*; javax.servlet.*; ...
- tcp短连接和长连接
1. TCP连接 当网络通信时采用TCP协议时,在真正的读写操作之前,server与client之间必须建立一个连接,当读写操作完成后,双方不再需要这个连接时它们可以释放这个连接,连接的建立是需要三次 ...
- win7下Oracle库imp导入dmp
第一步:创建备份文件存储目录 create or replace directory back_file as 'F:\APP\ADMINISTRATOR\ORADATA\ORCL'; create ...
- 学习python资料
资料链接:https://www.cnblogs.com/wupeiqi/articles/5433893.html
- Centos 7.5安装 Nginx 1.14.1
1. 准备工作 查看系统版本 输入命令 cat /etc/redhat-release 我的Centos版本 CentOS Linux release 7.5.1804 (Core) 安装nginx所 ...
- 使用 postman 给 API 写测试
使用 postman 给 API 写测试 Intro 上次我们简单介绍了 使用 postman 测试 API,这次主要来写一些测试用例以检查请求的响应是否符合我们的预期以及如何使用脚本测试 使用 po ...
- 网络知识_01:ISO七层模型
一 IOS七层模型 1.1OSI的概念 Open System Interconnect开放系统互连参考模型,是由ISO(国际标准化组织)定义的.它是个灵活的.稳健的和可互操作的模型. 1.2OSI模 ...
- 洛谷P5664 Emiya 家今天的饭 题解 动态规划
首先来看一道题题: 安娜写宋词 题目背景 洛谷P5664 Emiya 家今天的饭[民间数据] 的简化版本. 题目描述 安娜准备去参加宋词大赛,她一共掌握 \(n\) 个 词牌名 ,并且她的宋词总共有 ...
- Jmeter基础学习-下载及安装
1. Jmeter下载路径:http://jmeter.apache.org/download_jmeter.cgi 进入Jmeter下载界面后英语不好+技术不灵的同学会蒙圈,下载那个呢? *Bina ...
- 如何在Go项目中输出版本信息?
我们经常在使用CLI工具的时候,都会有这样的参数输出: ``` ➜ ~ docker version Client: Docker Engine - Community Version: 18.09. ...