正则表达式在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 通过构造器去使用正则表达式 需要对反斜 ...
随机推荐
- 解决netcore在docker容器中连接oracle报错(timezone region not found)
错误提示: timezone region not found错误原因:docker 容器内时区不是 CST 导致解决办法:1.在dockerfile 中增加一下命令ENV TZ=Asia/Shang ...
- ES安装&常见错误
ES常见错误 案例一 [2018-06-20T02:35:47,152][INFO ][o.e.b.BootstrapChecks ] [SUcoFrg] bound or publishing to ...
- 一键自动生成 java junit 测试代码神器 gen-test-plugin 入门介绍
gen-test-plugin 我们日常编写代码的过程中,经常需要为代码编写测试案例. 随着对代码质量的要求越来越高,很多公司开始通过代码的测试覆盖率作为 QA 的一个评定指标. 本框架可以一键生成所 ...
- 0016 CSS 背景:background
目标 理解 背景的作用 css背景图片和插入图片的区别 应用 通过css背景属性,给页面元素添加背景样式 能设置不同的背景图片位置 [插入图片,不用设置img元素的父元素.自身元素大小,即可见,但是背 ...
- DEVOPS技术实践_18:Jenkins的Pinpeline对于参数的使用
因为最近使用Pipeline声明式语法构建项目,但是最近项目的参数设置较多,特地的来学习一下关于参数的调用和测试,主要式从一个大神那里学习的,结尾回贴上大神的博客链接 1 构建一个pipeline项目 ...
- 【转载】JavaScript术语:shim 和 polyfill
在学习和使用 JavaScript 的时候,我们会经常碰到两个术语:shim 和 polyfill.它们有许多定义和解释,意思相近又有差异. Shim Shim 指的是在一个旧的环境中模拟出一个新 A ...
- 【题解】Leyni的汽车比赛
[题解]Leyni的汽车比赛 HRBUST - 1404 思维题?居然被我凑出来了 这种图论题先设这样一个状态 \[ ans(i,j,f) \] 表示从i到j,最多使用f个交通工具的最短路 转移的话, ...
- $CF809C\ Find\ a\ car$ 数位$dp$
正解:数位$dp$ 解题报告: 传送门! 然后因为没有翻译所以先放个翻译$QAQ$ 有一个无穷大的矩阵,第$i$行第$j$列的数是$(i-1)\ xor\ (j-1)+1$,有$q$次询问,每次询问一 ...
- JAVA字节码文件之常量池
一.常量池的内容 一个java类中定义的很多信息都是由常量池来维护和描述的,可以将常量池看作是class文件的资源仓库,比如java类中定义的方法与变量信息.常量池中主要存储两类常量:字面量(文本字符 ...
- 电脑端TIM登录时记住密码
为什么每次登录TIM时点了记住密码,下次再登录时还是记不住呢? 不是扫码就是还得输出密码,为这事愁了好多次, 最近终于发现如何记住密码了... 进入登录界面以后,点击左下角这个小图标>> ...