NFA to DFA Conversion

Source: Internet
Author: User

#include <iostream>#include <string>#include <cstring>#include <vector>#include <algorithm>#include <set>#define MAXusing namespace STD;structedge{CharPrenode;The //node indicates that only a single character can be used    CharNextNode;CharTchar//Convert characters};structNewj//Get the status set{stringSETJ;};structRelationtransitions between collections and collections{newj* Prej;CharJchar; Newj* NEXTJ;};voidGeteclosure (ConstEdge *e,intCntedge, NEWJ *st)//Get closures{ for(inti =0; I < st->setj.length (); i++)//Take out the state in each State collection{ for(intj =0; J < Cntedge; J + +)//test each edge{if(E[j].prenode = = St->setj[i] && E[j].tchar = =' 0 ')The //conversion character is ' 0 ', which is a null character{ST-&GT;SETJ + = E[j].nextnode; }        }    }}voidMoveCharTtchar, Edge *e,intCntedge, Newj *source, Newj *dest)The //e is a collection of all the edges, and then can get all from a converted character, such as 2 to get BD, not the first 2 to get B, the second 2 to get D{ for(inti =0; I < source->setj.length (); i++)//Take out the state in each State collection{ for(intj =0; J < Cntedge; J + +) {if(E[j].prenode = = Source->setj[i] && E[j].tchar = = Ttchar)            {DEST-&GT;SETJ + = E[j].nextnode; }        }    }}//By SETJ in the State collection to decide whether to addBOOLIsinsert ( vector<newJ*>Allset, Newj *newset) {BOOLb =true; for(intK =0; K < Allset.size (); k++) {if(allset.at (k)->setj = = NEWSET-&GT;SETJ) b =false; }returnb;}//Judging relation structural body de-weightBOOLIsinsertforrel ( vector<relation*>Relvec, newj* Prej,CharJchar, newj* nextj) {BOOLIsIn =true; for(inti =0; I < relvec.size (); i++) {if(relvec.at (i)->prej->setj = = Prej->setj && relvec.at (i)-&GT;NEXTJ-&GT;SETJ = NEXTJ-&GT;SETJ & & Relvec.at (i)->jchar = = Jchar) IsIn =false; }returnIsIn;}voidUniquechars (Char*arr,intNChar*outs) {memset(Outs,0,sizeof(Char) *n);CharFirst = arr[0]; for(inti =0; I < n;    i++) {Outs[arr[i]-first] = Arr[i]; }}//Rename TransformationvoidChangeName ( vector<newJ*>Allset, Newj *TJ,string& newstr) {NEWJ *TMPJ =NewNEWJ (); for(inti =0; I < allset.size (); i++) {if(TJ-&GT;SETJ = = allset.at (i)->setj) TMPJ-&GT;SETJ =' A '+ i; } newstr = TMPJ-&GT;SETJ;}intMain () {edge* E =NewEdge[max];intCntedge =0;CharStanode;//Start point and end point    stringEndnode;stringNode;//Node collection    intCntrealedge[max] = {0};//non-null character array of edges    cout<<"Enter the information for each side and convert the character (char ' a '-'-') ' in the ' preceding point (char ' a '-'-' z ') to the ' format ' of char ' a '-'-'-' 1 '-'-') ', ending with ' $ '<< Endl;cout<<"If the conversion character is empty, use ' 0 ' for"<< Endl;//Use Prenode TCHAR Nextnpde to enter the side. and end the input with ' $ '     for(inti =0; i < MAX; i++) {Cin>> E[i].prenode;if((e[i].prenode) = =' $ ') Break;Cin>> E[i].tchar >> E[i].nextnode;if(E[i].tchar = =' 0 ') Cntrealedge[cntedge] =1;    cntedge++; }//Put nodes in the edge edge into vectors     for(inti =0; i < Cntedge; i++) {CharPretmp = E[i].prenode;CharNexttmp = E[i].nextnode;//The nodes in the side are not included, add        if(Node.find (pretmp) > Node.length ()) Node + = pretmp;if(Node.find (nexttmp) > Node.length ())    Node + = nexttmp; }cout<<"Input initial point character"<< Endl;Cin>> Stanode; while(Node.find (stanode) = =string:: NPOs) {cout<<"Initial state input Error"<< Endl;Cin>> Stanode; }cout<<"Enter the terminating point character (if there is more than one end state, write directly as a string)"<< Endl;Cin>> Endnode;BOOLInputstatus =true; while(Inputstatus) { for(inti =0; I < endnode.length (); i++) {if(Node.find (endnode[i]) = =string:: NPOs) {cout<<"End state input Error"<< Endl;cout<<"Please re-enter:"<< Endl;Cin>> Endnode; }} inputstatus =false; } NEWJ *newset =NewNEWJ (); NEWSET-&GT;SETJ = Stanode;//Set initial point as State set IGeteclosure (E, Cntedge, newset);//     vector<newJ*>Allset (1, Newset);//Set vector for all state sets     vector<newJ*>:: Iterator iter;intSizeofstrvec =1;/* Used to store the state set of the first column before each closure operation * For example, the first time Strvec storage is the initial state, the closure of the packet when the 2 more state sets.    At the second time, the new 2 states are stored, and the original initial state is removed. * The total state collection is stored in allset */     vector<newJ*>Strvec (1, Newset); vector<relation*>Relvec; while(Sizeofstrvec)//If not compliant then the new collection is the original collection{intOldallset = Allset.size (); for(intj =0; J < Sizeofstrvec; J + +) { for(inti =0; i < Cntedge; i++)//For each letter to be similar to IK; this loop handles only one row{NEWJ *dest =NewNEWJ ();if(!cntrealedge[i])//Remove edges of empty conversion characters{Move (E[i].tchar, E, Cntedge, strvec.at (j), dest);//If there is a character on multiple edges, you want to set the same collation by character. Otherwise it will make the state set apart and cause errors!! Geteclosure (E, Cntedge, dest);//At this time dest for Ia,ib and the like.                     if(Isinsert (Allset, dest) && DEST-&GT;SETJ! ="")//not found and DEST->SETJ and not empty add{Allset.push_back (dest); }//When adding Relvec, as long as it is not empty to add, this will make reldest elements may be repeated (when one character appears in multiple edges)                    if(DEST-&GT;SETJ! ="") {relation* Reldest =NewRelation ();                        Reldest->prej = strvec.at (j);                        Reldest->jchar = E[i].tchar; RELDEST-&GT;NEXTJ = dest;BOOLIsIn = Isinsertforrel (Relvec, Reldest->prej, Reldest->jchar, RELDEST-&GT;NEXTJ);if(isIn)//de-weight{Relvec.push_back (reldest); }}}}} strvec.clear ();intNewallset = Allset.size (); for(inti = Oldallset; I < allset.size (); i++)//Add the new later elements in the Allset into the Strvec. {NEWJ *dest =NewNEWJ ();            Dest = allset.at (i);        Strvec.push_back (dest);    } Sizeofstrvec = Strvec.size (); }cout<<"Conversion Results"<< Endl; vector<relation*>:: Iterator Reliter; for(Reliter = Relvec.begin (); Reliter! = Relvec.end (); reliter++) {cout<< (*reliter)-&GT;PREJ-&GT;SETJ <<" "<< (*reliter)->jchar <<" "<< (*reliter)->nextj->setj << Endl; }Charupperchars[ -];memset(Upperchars,0,sizeof(Char) * -);cout<<"Rename as follows:"<< Endl; for(inti =0; I < allset.size (); i++) {Upperchars[i] =' A '+ i;cout<< Upperchars[i] <<":"<< allset.at (i)-&GT;SETJ << Endl; } vector<relation*>Newrelvec;//Relvec after renaming     for(inti =0; I < relvec.size (); i++) {relation* Newrel =NewRelation ();stringPrenew, Nextnew;        ChangeName (Allset, relvec.at (i)->prej, prenew);        ChangeName (Allset, relvec.at (i)-&GT;NEXTJ, nextnew); newj* Tprej =NewNEWJ (); newj* TNEXTJ =NewNEWJ ();        Newrel->prej = Tprej;        NEWREL-&GT;NEXTJ = TNEXTJ;        NEWREL-&GT;PREJ-&GT;SETJ = prenew;        NEWREL-&GT;NEXTJ-&GT;SETJ = nextnew;        Newrel->jchar = relvec.at (i)->jchar;    Newrelvec.push_back (Newrel); }//output validation of renamed collection Relationships    cout<<"Final conversion:"<< Endl; vector<relation*>:: Iterator Newreliter; for(Newreliter = Newrelvec.begin (); Newreliter! = Newrelvec.end (); newreliter++) {cout<< Endl << (*newreliter)-&GT;PREJ-&GT;SETJ <<" "<< (*newreliter)->jchar <<" "<< (*newreliter)->nextj->setj << Endl; }//Derive initial state and acceptance status    cout<<"Accept status is:"<< Endl;intoutsize = Allset.size ();Char*output =New Char[Outsize];memset(Output,0,sizeof(Char) *outsize);intoutputcnt =0; for(intK =0; K < Allset.size (); k++) { for(inti =0; I < endnode.length (); i++) {if((allset.at (k)->setj). Find (Endnode[i])! =string:: NPOs) output[outputcnt++] =' A '+ K; }    }//Array de-heavy output    Char*outsfinal =New Char[OUTPUTCNT]; Uniquechars (output, outputcnt, outsfinal); for(inti =0; i < outputcnt; i++) {if(Outsfinal[i]! =' + ')cout<< outsfinal[i]<<" "; } System ("Pause");}


The code has a more detailed comment that can be tested for any form of NFA-to-DFA conversion.

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

NFA to DFA Conversion

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.