前几天突然想写一个正则表达式引擎,于是计划用5个小时搞定一个一般的RegexEngine. 不过断断续续加起来严重超时,写了十几个小时,大体功能完成。 写一个正则表达式需要考虑的内容还是不少的。
比如: 0 词法分析:涉及到怎么划分原子粒度,我把/[A..Z1..5_]/作为一个词法元素,另外用一张表索引子词法元素 1 语法分析:直接一个函数递归消化掉所有分析并转化为Epsilon-NFA,其中*号要避免空回路。 2 表达式匹配:同样一个递归消化掉所有内容,E-NFA处理空串匹配时要单独处理。
由于用到了自己上一年写的泛化adt::graph类,所以图结构基本没花很多时间,给graph扩展了一个E-NFA匹配的功能。
700行的ProBetaMinus版本,到完整的Beta版本,估计要增加200行代码(加入重复描述符检测和{m,n},{m,n}处理估计要用到递归+函数内临时堆栈).此外我会对自己的adt::graph类做一个优化,确保其更好的支持Regex.
用了几十个case,目前没发现Bug,不过随着以后使用的过程,肯定会出现不同的BUG。
/**//*regex.h :vgl::regex*/ /**//*---------------------------------------------------------------------------- Simplex v1.2 Developer: Zblc vgl::regex
enumes:
classes: AtomToken :原子词 Regex :正则表达式分析类
macros: MAX_SUB_ROW :[]的最大数 MAX_SUB_COW :[]中原子字符的最大数 MAX_TOKEN :最大接受的原子字符数 CAPA_LIST :调试用 CAPA_LIST_LETTER :调试用 namespace variable: AtomToken subList[MAX_SUB_ROW][MAX_SUB_COW]; :存储正则表达式中每个[]中原子字符 static int subListLen[MAX_SUB_ROW]; :存储正则表达式中每个[]中原子字符个数 static int subLen; :存储正则表达式中[]的个数
includes: graph.h :VGL::ADT::有向图
-------------------------------------------------------------------------------*/
#ifndef REGEX__ #define REGEX__
#include "graph.h"
namespace simplex { typedef char AtomChar; enum AtomType{AtomNormChar,AtomRangeLeft,AtomRangeRight,AtomRangeOne,AtomRangeBoth,AtomLeftMB, AtomRightMB,AtomLeftBB,AtomRightBB,AtomLeftSB,AtomRightSB, AtomNormESC,AtomMoreOne,AtomMoreZero,AtomZeroOne,AtomNot, AtomBegin,AtomEnd,AtomDigit,AtomNotDigit,AtomLetter,AtomNotLetter, AtomAny,AtomLetterRange,AtomDigitRange,AtomMu,AtomOr,AtomOrList,AtomNotAndList};
#define CAPA_LIST 35 #define CAPA_LIST_LETTER 25 char list[CAPA_LIST][CAPA_LIST_LETTER]={"AtomNormChar","AtomRangeLeft","AtomRangeRight","AtomRangeOne","AtomRangeBoth","AtomLeftMB", "AtomRightMB","AtomLeftBB","AtomRightBB","AtomLeftSB","AtomRightSB", "AtomNormESC","AtomMoreOne","AtomMoreZero","AtomZeroOne","AtomNot", "AtomBegin","AtomEnd","AtomDigit","AtomNotDigit","AtomLetter","AtomNotLetter", "AtomAny","AtomLetterRange","AtomDigitRange","AtomMu","AtomOr","AtomOrList","AtomNotAndList"};
#define MAX_SUB_ROW 50 #define MAX_SUB_COW 30 #define MAX_TOKEN 200
static int subListLen[MAX_SUB_ROW]; static int subLen; class AtomToken;
class AtomToken { public:
AtomChar c[3]; AtomType type; int subIndex;
AtomToken() { memcpy(c,"",3); type=AtomNormChar; subIndex=0;
} ~AtomToken() { subIndex=0; } AtomToken* operator=(AtomToken& _copy) {
memcpy(c,_copy.c,3*sizeof(char)); type=_copy.type;
subIndex=_copy.subIndex; return this;
} int operator ==(AtomToken & _token) {
AtomToken* b,*ob;
if(type==AtomNormChar) { b=&_token; ob=this; }else { b=this; ob=&_token; }
if(b->type==AtomMu) {
return 2; }
switch(b->type) { case AtomNotAndList: case AtomOrList:
for(int j=0;j!=subListLen[b->subIndex];j++) {
if(subList[b->subIndex][j]==*ob) return 1; } return 0; case AtomAny: return ob->type==AtomNormChar; case AtomNormChar: return b->c[0]==ob->c[0]; case AtomNormESC: switch(b->c[0]) { case 'd': return ob->c[0]>='0'&&ob->c[0]<='9'; case 'D': return ob->c[0]<'0'||ob->c[0]>'9'; case 'b': return (ob->c[0]>='a'&&ob->c[0]<='z')||(ob->c[0]>='A'&&ob->c[0]<='Z'); case 'B': return (ob->c[0]<'a'||ob->c[0]>'z')&&(ob->c[0]<'A'||ob->c[0]>'Z');
} return _token.c[0]==c[0];
case AtomDigitRange: return ob->c[0]>=b->c[0]&&ob->c[0]<=b->c[1]; case AtomLetterRange:
return ob->c[0]>=b->c[0]&&ob->c[0]<=b->c[1];
default: return 0; } }
}subList[MAX_SUB_ROW][MAX_SUB_COW];
class Regex /**//* Regex Analyser :Scanning and Grammar,Match*/ { protected: AtomToken tokens[MAX_TOKEN]; adt::graph<int,AtomToken> nfa;/**//* Epsilon-NFA */ int len; int isDigit(char c) { return c<='9'&&c>='0'; } int isLetter(char c) { return (c<='z'&&c>='a')||(c<='Z'&&c>='A'); } int getFirstNum(char * _buf,int & _len) { int i,num=0; for(i=0;isDigit(_buf[i]);i++); _len=i; i--; for(int j=0;i!=-1;i--,j++) {
num+=(_buf[i]-'0')*atom::pow10(j); } return num;
} AtomToken* buf_tokens; public: Regex() { subLen=0; } ~Regex() { if(!buf_tokens) delete []buf_tokens; } void atomParse(char* _buf) {
int buf_len=atom::lenof(_buf),temp_len=0; len=0; AtomToken _list[MAX_SUB_COW]; int lenList=0; for(int i=0;i!=buf_len;) { switch(_buf[i]) { case '^':
tokens[len].c[0]='^'; if(i==0) tokens[len].type=AtomBegin; else tokens[len].type=AtomNot; i++; break; case '.': tokens[len].c[0]='.'; tokens[len].type=AtomAny;
i++; break; case '|': tokens[len].c[0]='|'; tokens[len].type=AtomOr;
i++; break;
case '+': tokens[len].c[0]='+'; tokens[len].type=AtomMoreOne;
i++; break;
case '*': tokens[len].c[0]='*'; tokens[len].type=AtomMoreZero; i++; break;
case '?': tokens[len].c[0]='?'; tokens[len].type=AtomZeroOne; i++; break; case '$': tokens[len].c[0]='$'; tokens[len].type=AtomZeroOne; i++; break; case '{':
if(_buf[i+1]==',') { tokens[len].c[0]=getFirstNum(&_buf[i+2],temp_len); tokens[len].type=AtomRangeRight; i+=temp_len+3; break; }else { tokens[len].c[0]=getFirstNum(&_buf[i+1],temp_len); tokens[len].type=AtomRangeLeft; if(_buf[i+temp_len+1]==',') { if(isDigit(_buf[i+temp_len+2])) { i+=temp_len+2; tokens[len].type=AtomRangeBoth; tokens[len].c[1]=getFirstNum(_buf+i+temp_len+2,temp_len); i+=temp_len; if(_buf[i]=='}') { i++; break; }else { cout<<"Error\n"; break; }
}else if(_buf[i+temp_len+2]=='}') { i+=temp_len+3; tokens[len].type=AtomRangeLeft; break; } }else if(_buf[i+temp_len+1]=='}') { i+=temp_len+2; tokens[len].type=AtomRangeOne; break; }
}
case '[':
lenList=0; if(_buf[i+1]!='^') { tokens[len].type=AtomOrList; }else { i++; tokens[len].type=AtomNotAndList; } i++;
for(;_buf[i]!=']';) { if(isDigit(_buf[i])) {
if(i+4<buf_len) { if(_buf[i+1]=='.'&&_buf[i+2]=='.'&&isDigit(_buf[i+3])) { _list[lenList].c[0]=_buf[i]; _list[lenList].c[1]=_buf[i+3]; _list[lenList].type=AtomDigitRange; lenList++; i+=4; continue; }else { _list[lenList].c[0]=_buf[i]; _list[lenList].type=AtomNormChar; lenList++; i++; continue; } }else { _list[lenList].c[0]=_buf[i]; _list[lenList].type=AtomNormChar; lenList++; i++; continue; } }else if(isLetter(_buf[i])) {
if(i+4<buf_len) {
if(_buf[i+1]=='.'&&_buf[i+2]=='.'&&isLetter(_buf[i+3])) {
_list[lenList].c[0]=_buf[i]; _list[lenList].c[1]=_buf[i+3]; _list[lenList].type=AtomLetterRange; lenList++; i+=4; continue; }else { _list[lenList].c[0]=_buf[i]; _list[lenList].type=AtomNormChar; lenList++; i++; continue; } }else { _list[lenList].c[0]=_buf[i]; _list[lenList].type=AtomNormChar; lenList++; i++; continue; } }else { switch(_buf[i]) { case '\\': i++; switch(_buf[i]) { case '|': case '\\': case '(': case ')': case '[': case ']': case '{': case '}': case '*': case '?': case '+': case '^': case '$': case '.': _list[lenList].c[0]=_buf[i]; _list[lenList].type=AtomNormChar; lenList++; i++; break; case 'd': case 'D': case 'b': case 'B': _list[lenList].c[0]=_buf[i]; _list[lenList].type=AtomNormESC; lenList++; i++; break; } } } } for(int j=0;j!=lenList;j++) { subList[subLen][j]=_list[j]; } tokens[len].subIndex=subLen; subListLen[subLen++]=lenList; ++i; break;
case '(': tokens[len].c[0]='('; tokens[len].type=AtomLeftSB; i++; break; case ')': tokens[len].c[0]=')'; tokens[len].type=AtomRightSB; i++; break; case '\\': i++; switch(_buf[i]) { case '|': case '\\': case '(': case ')': case '[': case ']': case '{': case '}': case '*': case '?': case '+': case '^': case '$': case '.': tokens[len].c[0]=_buf[i]; tokens[len].type=AtomNormChar; i++; break; case 'd': case 'D': case 'b': case 'B': tokens[len].c[0]=_buf[i]; tokens[len].type=AtomNormESC; i++; break; } break; default:
tokens[len].c[0]=_buf[i]; tokens[len].type=AtomNormChar; i++; break;
} len++; } #ifdef TEST_OPEN_CONSOLE /**//* DEBUG:display all the results */ cout<<"\nScanning list:\nPrinting format:Token[i](Type,Attribut_1,Attribute_2)\n"; for(int k=0;k!=len;k++) { cout<<"Token["<<k<<"]:(\'"; cout<<list[tokens[k].type]<<"\',\'"; cout<<tokens[k].c[0]<<"\',\'"<<tokens[k].c[1]<<"\')\t\n";
} #endif
} enum NfaStatus{NfaBegin,NfaNormState,NfaEnd};
void grammarParse(int _index=0,int _deep=0) {
static AtomToken token;
static int numArc; static int lastKey,nowKey,lastBegin; static int i; if(_index==0) {
lastBegin=1; nowKey=1; numArc=1; }
int beginNode,endNode;
nfa.addNode(nowKey,NfaBegin,0); beginNode=nowKey++; nfa.addNode(nowKey,NfaEnd,0); endNode=nowKey++;
if(_index!=0) { token.type=AtomMu; nfa.addArc(lastKey,beginNode,numArc++,token); } lastKey=beginNode;
int temp=0;
for(i=_index;i!=len;i++) {
switch(tokens[i].type) { case AtomBegin: break; case AtomEnd: break; case AtomRightSB: temp=1; if(i+1!=len) { if(tokens[i+1].type==AtomMoreOne) { token.type=AtomMu; nfa.addArc(endNode,beginNode,numArc++,token); }else if(tokens[i+1].type==AtomMoreZero) { token.type=AtomMu; nfa.addNode(nowKey,NfaNormState,0);
nfa.addArc(beginNode,endNode,numArc++,token);
nfa.addArc(lastKey,nowKey,numArc++,token);
nfa.addArc(nowKey,beginNode,numArc++,token);
lastKey=nowKey++;
//AtomRangeLeft,AtomRangeRight,AtomRangeOne,AtomRangeBoth }else if(tokens[i+1].type==AtomRangeLeft) {
} }
break; case AtomLeftSB: grammarParse(i+1,_deep+1); break; case AtomLeftMB: grammarParse(i,_deep+1); break; case AtomAny: case AtomOrList: case AtomNotAndList: case AtomNormESC: case AtomNormChar: nfa.addNode(nowKey,NfaNormState,0);
nfa.addArc(lastKey,nowKey,numArc++,tokens[i]);
if(i+1!=len) { if(tokens[i+1].type==AtomMoreOne) { nfa.addArc(lastKey,lastKey,numArc++,tokens[i]); }else if(tokens[i+1].type==AtomMoreZero) {
token.type=AtomMu; nfa.addArc(lastKey,nowKey,numArc++,token); nfa.addArc(lastKey,lastKey,numArc++,tokens[i]); } } lastKey=nowKey++;
break;
case AtomOr:
token.type=AtomMu; nfa.addArc(lastKey,endNode,numArc++,token);
nfa.addNode(nowKey,NfaNormState,0); nfa.addArc(beginNode,nowKey,numArc++,token); lastKey=nowKey++;
break;
default: break; } if(temp==1) break;
} token.type=AtomMu; nfa.addArc(lastKey,endNode,numArc++,token); lastKey=endNode; lastBegin=beginNode;
} void parse(char* _buf) { atomParse(_buf);
grammarParse();
}
int match(char* _buf=0) {
int buf_len=atom::lenof(_buf),buf_max,temp; buf_tokens=new AtomToken[buf_len]; for(int i=0;i!=buf_len;i++) { buf_tokens[i].c[0]=_buf[i]; }
/**//*Restricted in beginning match*/ buf_max=(tokens[0].type==AtomBegin)?1:buf_len;
for(int i=0;i!=buf_max;i++) {
if(temp=nfa.isGoEPath(1,buf_tokens,buf_len,i,2)) {
if(tokens[len-1].c[0]=='$') {
if(temp==2) return 1; else return 0; }else { return 1; } } } return 0; }
}; }
#endif
另附用到的自己上一年写的adt::graph类.
/**//* graph.h :base::adt::graph */
#ifndef GRAPH__
#define GRAPH__
#include "base.h" #include "vector.h"
namespace adt { using adt::vector; template<typename VTypeN,typename VTypeE> class graph : public base::adt { public: struct VArc; struct VNode; struct VArc { VNode* begin; VNode* end;
int *tag_begin; int *tag_end; VTypeE weight;
int tag;/**//*internal index tag*/ int key;/**//*external index tag*/
VArc() { tag=0; key=0; } VArc(VNode *_begin,VNode * _end,int _key,int _tag,VTypeE _w) { begin=_begin; end=_end; weight=_w; tag=_tag; key=_key; tag_begin=&begin->tag; tag_end=&end->tag; } ~VArc() { begin=0; end=0; tag=0; key=0; } /**//*copy to _arc only by data not adr*/ void copyTo(VArc * _arc) { _arc->weight=weight; _arc->tag=tag; _arc->key=key; } void setKey(int _key) { key=_key; } void setTag(int _tag) { tag=_tag; } void setWeight(VTypeE _w) { weight=_w; } void setBegin(VNode* _begin) { begin=_begin; tag_begin=&begin->tag;
} void setEnd(VNode* _end) { end=_end; tag_end=&end->tag; } }; struct VNode { vector<VArc*> inArc; vector<VArc*> outArc; int &inNum; int &outNum;
VTypeN weight;
int tag;/**//*internal index tag*/ int key;/**//*external index tag*/
int status;/**//*node status*/
/**//*copy to _arc only by data not adr*/ void copyTo(VNode * _node) { _node->weight=weight; _node->tag=tag; _node->key=key; _node->status=status;
} VNode():/**//*build up ref*/inNum(inArc.n),outNum(outArc.n) { status=0; tag=0; key=0; } VNode(int _key,int _tag,VTypeN _w,int _status):/**//*build up ref*/inNum(inArc.n),outNum(outArc.n) { weight=_w; status=_status; tag=_tag; key=_key; } ~VNode() { tag=0; key=0; status=0; } /**//* set key */ void setKey(int _key) { key=_key; } /**//* set tag */ void setTag(int _tag) { tag=_tag; } /**//* set weight */ int setWeight(VTypeN _w) { weight=_w; return 1; } /**//* set status */ void setStatus(int _status) { status=_status; }
/**//* add inArc */ int addIn(VArc *_inArc ) { if(!_inArc) return 0; inArc.push(_inArc); //++inNum; return 1; } /**//* and outArc */ int addOut(VArc *_outArc ) { if(!_outArc) return 0; outArc.push(_outArc); //++outNum; return 1; }
/**//* remove inArc by weight */ int removeInWeight(VTypeE _w) { for(int i=0;i!=inArc_.n;i++) { if(inArc[i]->weight==_w) { inArc.remove(i); //--inNum; --i; } } return 1; } /**//* remove outArc by weight */ int removeOutWeight(VTypeE _w) { for(int i=0;i!=outArc_.n;i++) { if(outArc[i]->weight==_w) { outArc.remove(i); //--outNum; --i; } } return 1; } /**//* remove inArc by tag */ int removeInTag(int _tag) { for(int i=0;i!=inArc.n;i++) { if(inArc[i]->tag==_tag) { inArc.remove(i); //--inNum; return 1; } } return 0; } /**//* remove outArc by tag */ int removeOutTag(int _tag) { for(int i=0;i!=outArc.n;i++) { if(outArc[i]->tag==_tag) { outArc.remove(i); //--outNum; return 1; } } return 0; } /**//* remove inArc by key */ int removeInKey(int _key) { for(int i=0;i!=inArc_.n;i++) { if(inArc[i]->key==_key) { inArc.remove(i); //--inNum; return 1; } } return 0; } /**//* remove outArc by key */ int removeOutKey(int _key) { for(int i=0;i!=outArc_.n;i++) { if(outArc[i]->key==_key) { outArc.remove(i); //--outNum; return 1; } } return 0; } /**//* search inArc by weight */ VArc* findInWeight(VTypeE _w) { for(int i=0;i!=inArc_.n;i++) { if(inArc[i]->weight==_w) { return inArc_[i]; } } return 0;
} /**//* search outArc by weight */ VArc* findOutWeight(VTypeE _w) { for(int i=0;i!=outArc.n;i++) { if(outArc[i]->weight==_w) { return outArc[i]; } } return 0;
} /**//* search inArc by tag */ VArc* findInTag(int _t) { for(int i=0;i!=inArc.n;i++) { if(inArc[i]->tag==_t) { return inArc[i]; } } return 0;
} /**//* search outArc by tag */ VArc* findOutTag(int _t) { for(int i=0;i!=outArc_.n;i++) { if(outArc[i]->tag==_t) { return outArc_[i]; } } return 0;
} /**//* search inArc by key */ VArc* findInKey(int _key) { for(int i=0;i!=inArc_.n;i++) { if(inArc[i]->key==_key) { return inArc_[i]; } } return 0;
} /**//* search outArc by key */ VArc* findOutKey(int _key) { for(int i=0;i!=outArc_.n;i++) { if(outArc[i]->key==_key) { return outArc_[i]; } } return 0;
} }; vector<VNode*> allNode; vector<VArc*> allArc; int& nodeNum; int& arcNum; graph():/**//*build up ref*/nodeNum(allNode.n),arcNum(allArc.n) {
} graph(graph & obj):/**//*build up ref*/nodeNum(allNode.n),arcNum(allArc.n) { obj.copyTo(*this); } int addNode(int _key,VTypeN _w,int _status) {
if(findNodeTag(_key)!=-1) {
#ifdef TEST_OPEN TEST_THROW("Exception in graph.h graph::addNode Function.") #endif return 0;
}
VNode* _node=new VNode; /**//*init data*/ _node->setKey(_key); _node->setWeight(_w); _node->setStatus(_status); _node->setTag(nodeNum);/**//*index reciprocally beginning with 0 */ /**//*push in index list*/ allNode.push(_node); return 1; } int setNode(int _key,VTypeN _w,int _status) { int _tag;
if((_tag=findNodeTag(_key))==-1) {
#ifdef TEST_OPEN TEST_THROW("Exception in graph.h graph::setNode Function.") #endif return 0;
}
VNode* _node=allNode[_tag]; /**//*init data*/ _node->setWeight(_w); _node->setStatus(_status); return 1; } /**//* switch key to tag */ int findNodeTag(int _key) { for(int i=0;i!=allNode.n;i++) { if(allNode[i]->key==_key) { return allNode[i]->tag; } } return -1; } /**//* switch key to tag */ int findArcTag(int _key) { for(int i=0;i!=allArc.n;i++) { if(allArc[i]->key==_key) { return allArc[i]->tag; } } return -1; } /**//* find node by key */ int findNode(int _key) { for(int i=0;i!=allNode.n;i++) { if(allNode[i]->key==_key) { return 1; } } return 0; } /**//* find arc by key */ int findArc(int _key) { for(int i=0;i!=allArc.n;i++) { if(allArc[i]->key==_key) { return 1; } } return 0; } int isGo(int _key,VTypeE _w,int &_next_key) {
int _tag = findNodeTag(_key);
if(_tag>=nodeNum||_tag==-1) {
#ifdef TEST_OPEN TEST_THROW("Exception in graph.h graph::isGo function.") #endif return 0; }
VNode * _node = allNode[_tag];
VArc* _arc = _node->findOutWeight(_w);
if(!_arc) return 0; _next_key = _arc->end->key; return 1; } int getStatus(int _key) { int _tag = findNodeTag(_key);
return allNode[_tag]->status; } /**//* add arc by begin and end 's key */ void addArc(int _k_begin,int _k_end,int _key,VTypeE& _w) { if(findArcTag(_key)!=-1) {
#ifdef TEST_OPEN TEST_THROW("Exception in graph.h graph::addArc function.") #endif return;
} VArc* _arc=new VArc; /**//* switch key to tag,get begin's and end's adr*/ int _tag_begin = findNodeTag(_k_begin); int _tag_end = findNodeTag(_k_end); VNode* _begin=allNode[_tag_begin]; VNode* _end =allNode[_tag_end]; /**//*init data*/ _arc->setBegin(_begin); _arc->setEnd(_end); _arc->setKey(_key); _arc->setWeight(_w); /**//*index reciprocally beginning with zero */ _arc->setTag(arcNum); /**//*building begin-end link.*/ _begin->addOut(_arc); _end->addIn(_arc); /**//*push in index list*/ allArc.push(_arc);
} int setArc(int _key,VTypeE& _w) { int _tag; if((_tag=findArcTag(_key))==-1) {
#ifdef TEST_OPEN TEST_THROW("Exception in graph.h graph::setArc function.") #endif return 0;
} VArc* _arc=allArc[_tag];
VNode* _begin=allNode[_arc->begin->tag]; VNode* _end =allNode[_arc->end->tag]; /**//*init data*/ _arc->setBegin(_begin); _arc->setEnd(_end); _arc->setWeight(_w);
} /**//* copy self to graph-obj */ int copyTo(graph & _obj) { VNode *_node; VArc *_arc;
for(int i=0;i!=nodeNum;i++) { _node=allNode[i]; _obj.allNode.push(new VNode(_node->key,_node->tag,_node->weight,_node->status));
} for(int i=0;i!=arcNum;i++) { _arc=allArc[i]; _obj.addArc(_arc->begin->key,_arc->end->key,_arc->key,_arc->weight); } return 1; } int copyFrom(graph & _obj) { _obj.copyTo(*this); return 1; } /**//* get value from rightObj */ void operator = (graph& _rObj) { copyFrom(_rObj); } /**//* remove arc by tag */ int removeArcTag(int _tag) {
VArc* _arc=allArc[_tag]; _arc->begin->removeOutTag(_tag); _arc->end->removeInTag(_tag); allArc.remove(_tag); for(int i=_tag;i!=arcNum;i++) --allArc[i]->tag;
return 1; } /**//* remove arc by key */ int removeArcKey(int _key) { VArc* _arc;
/**//* search by key */
for(int i=0;i!=arcNum;i++) { if(allArc[i]->key==_key) { _arc=allArc[i]; removeArcTag(_arc->tag); return 1; } }
return 0; } /**//* remove node by tag*/ int removeNodeTag(int _tag) {
VNode* _node=allNode[_tag];
/**//* remove all inArc */ for(;0!=_node->inNum;) {
removeArcTag(_node->inArc[0]->tag); //_node->inArc.remove(0); } /**//* remove all outArc */ for(;0!=_node->outNum;) {
removeArcTag(_node->outArc[0]->tag); //cout<<_node->outNum; //_node->outArc.remove(0); } /**//* remove itself*/ allNode.remove(_tag); for(int i=_tag;i!=arcNum;i++) --allArc[i]->tag; return 1; } /**//* remove node by key*/ int removeNodeKey(int _key) {
VNode* _node; /**//* search by key */
for(int i=0;i!=nodeNum;i++) { if(allNode[i]->key==_key) { _node=allNode[i];
removeNodeTag(_node->tag); return 1; } }
return 0; }
int isGoEPath(int _beginKey,VTypeE * _edges,int _num,int _pos,int _endKey,int _deep=-1,int _type=25) {
_deep++; static int temp=0,result; if(_pos>=_num+1) { _deep--; return 0; }if(_deep==0) result=0; int _tag = findNodeTag(_beginKey);
VNode * _node = allNode[_tag];
for(int i=0;i!=_node->outArc.n;i++) {
if(_node->outArc[i]->weight.type!=_type) { if((_node->outArc[i]->weight==_edges[_pos])==2) {
if(_node->outArc[i]->end->key==_endKey&&_pos>=_num) { _deep--; return 2; }else if(_node->outArc[i]->end->key==_endKey) { _deep--; return 1; } if(temp=isGoEPath(_node->outArc[i]->end->key,_edges,_num,_pos,_endKey,_deep)) if(_deep!=0) { _deep--; return temp; }else if(temp==2) { _deep--; return temp; }else result=1; }else if((_node->outArc[i]->weight==_edges[_pos])==1) {
if(_node->outArc[i]->end->key==_endKey&&_pos>=_num) { _deep--; return 2; }else if(_node->outArc[i]->end->key==_endKey) { _deep--; return 1; }if(temp=isGoEPath(_node->outArc[i]->end->key,_edges,_num,_pos+1,_endKey,_deep)) if(_deep!=0) { _deep--; return temp; }else if(temp==2) { _deep--; return temp; }else result=1; }else { continue; } } } for(int i=0;i!=_node->outArc.n;i++) {
if(_node->outArc[i]->weight.type==_type) { if((_node->outArc[i]->weight==_edges[_pos])==2) {
if(_node->outArc[i]->end->key==_endKey&&_pos>=_num) { _deep--; return 2; }else if(_node->outArc[i]->end->key==_endKey) { _deep--; return 1; } if(temp=isGoEPath(_node->outArc[i]->end->key,_edges,_num,_pos,_endKey,_deep)) if(_deep!=0) { _deep--; return temp; }else if(temp==2) { _deep--; return temp; }else result=1; }else if((_node->outArc[i]->weight==_edges[_pos])==1) {
if(_node->outArc[i]->end->key==_endKey&&_pos>=_num) { _deep--; return 2; }else if(_node->outArc[i]->end->key==_endKey) { _deep--; return 1; }if(temp=isGoEPath(_node->outArc[i]->end->key,_edges,_num,_pos+1,_endKey,_deep)) if(_deep!=0) { _deep--; return temp; }else if(temp==2) { _deep--; return temp; }else result=1; }else { continue; } } } _deep--; if(result==1) {
return 1; } return 0;
} int free() {
for(;0!=nodeNum;) { delete allNode.pop();
} for(;0!=arcNum;) {
delete allArc.pop(); }
return 1; } ~graph() {
free();
}
}; };
#endif
一个Demo的代码:
/**//* init.h */
#include "frame.h"
#include "conio.h" #include "runtime.h"
#include "regex.h" using simplex::Regex; int cpp(){
cout<<"【VGL::Regex()v.1.0】\n";
while(1) {
char buf[100],buf_2[500]; int len; cout<<"Regex>>>";os::control::read(buf,len,'\n'); cout<<"String>>>";os::control::read(buf_2,len,'\n');
Regex re; re.parse(buf); cout<<endl; cout<<(re.match(buf_2)?"〖True〗":"〖False〗"); cout<<endl<<endl; } return 0; }
其运行结果:
|
|
随笔:30
文章:0
评论:146
引用:0
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
---|
24 | 25 | 26 | 27 | 28 | 29 | 30 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 1 | 2 | 3 | 4 |
|
常用链接
留言簿(11)
随笔分类
随笔档案
文章分类
相册
搜索
最新评论
阅读排行榜
评论排行榜
|
|