NFA转DFA 子集构造法(Dev C++)

参考资料:www.doc88.com/p-6843897482339.html

代码:

#include<iostream>
#include<fstream>
#include<algorithm>
#include<queue>
#include<string.h>
#include<stack>
using namespace std;

int n;//n为边数
int nk=0;//nk为空字符转换的边数
int f[200];//状态属性标志0为初始态,1为终态,-1为中间态;
int numof_Dtran=0;//最后得到的DFA中的状态数
char Dtran[100][100];//DFA状态转换表;
int first,accept;//初态   终态
int useof_DFA[100];//标志构造出来的状态是否已存在
int numof_char=0;//字母表中的字符个数
int useof_char[256];//该转换字符是否用过
char alpha[100];//输入字母表,#代表空串
struct State{
    int H[100];//状态集合
    int count;//状态集合中的元素个数
    int flag;//是否是接受状态
    int mark;//状态编号
};
State DFA[100];//DFA状态集
 
struct edge{
    int start,end;
    char c;
}E[100],Ekong[100];//E保存所有的边,Ekong保存转换字符为空的边;
void input(){
    ifstream fin("input.txt",ios::in);
    int i,s,e;
    char ch;
    fin>>n;
    cout<<"此状态转换有"<<n<<"条边"<<endl;
    fin>>first;
    cout<<"开始状态为:"<<first<<endl;
    memset(f,-1,sizeof(f));
    memset(useof_char,0,sizeof(useof_char));
    f[first]=0;
    cout<<"接受状态集为:";
    fin>>accept;
    while(accept!=-1){
        f[accept]=1;
        cout<<accept<<" ";
        fin>>accept;
    }
    cout<<"\n\n起点,终点,转换字符(’#‘表示空字符):" <<endl;
    int k=0;
    for(i=0;i<n;i++){
        fin>>s>>e>>ch;
        cout<<s<<" "<<e<<" "<<ch<<endl;
        E[i].start =s;
        E[i].end =e;
        E[i].c =ch;
        //收集转换字母表
        if(ch!='#'&&!useof_char[ch]){
            alpha[numof_char++]=ch;
            useof_char[ch]=1;
        }
        if(ch=='#'){
            Ekong[nk].start =s;
            Ekong[nk].end =e;
            Ekong[nk].c =ch;
            nk++;
        }
    }
    
    cout<<"状态属性标志数组f情况!"<<endl;
    for( i=0;i<10;i++) cout<<f[i]<<" ";
    cout<<endl<<"*************"<<endl;
}
//状态t通过不定个#字符到达的状态!
void arriveByone(int t,int result[],int& num){
    int k=0;
    int m=0;
    num=0;
    stack<int> S;
    S.push(t);
    int j;
    while(!S.empty() ) {
        j=S.top() ;
        S.pop() ;
        m=0;
        while(m<nk){//为什么m<nk ?nk是空字符转换的边数!
            if(Ekong[m].start==j){
                result[num++]=Ekong[m].end ;
                S.push(Ekong[m].end );  
            }
            m++;
        }
    }
}
//判断状态i是否在状态集T中
bool check(int i,State T){
    int j;
    for(j=0;j<T.count;j++){
        if(T.H[j]==i)
          return true;
    }
    return false;
}
State closure(State T){
    stack<int> STACK;
    State temp;
    int i,j,k;
    for(i=0;i<T.count;i++){
        STACK.push(T.H[i]);//将状态集里面的每一个元素压入栈中
        temp.H [i]=T.H[i];
    }
    temp.count =T.count;
    temp.mark =T.mark;
    temp.flag =-1;
//    cout<<"closure方法里:while循环之前:"<<temp.flag <<endl;
    while(!STACK.empty() ){
        int t=STACK.top() ;
        STACK.pop() ;
        //搜索状态T通过空字符到达的状态
        int search_result[100];
        int num;
        arriveByone(t,search_result,num);
        for(j=0;j<num;j++){
            if(!check(search_result[j],temp)){
                temp.H [temp.count ++]=search_result[j];
                STACK.push(search_result[j]);
            }
        }  
    }
//    cout<<"closure方法里:while循环之后:"<<temp.flag <<endl;
    //判断完善之后的状态集是初态还是终态还是中间态!
    for(k=0;k<temp.count ;k++){
    //    cout<<temp.H[k]<<" ";
        if(f[temp.H [k]]==1){
            temp.flag =1;
            break;
        }
        if(f[temp.H [k]]==0){
            temp.flag =0;
            break;
        }
        
    }
//    cout<<endl;
    //判断新形成的状态集和已形成的状态集是否有相同的!
    sort(temp.H ,temp.H +temp.count );
    for(i=0;i<numof_Dtran;i++){
        if(temp.count !=DFA[i].count)
           continue;
        sort(DFA[i].H,DFA[i].H+DFA[i].count);
        for(j=0;j<DFA[i].count;j++){
            if(DFA[i].H[j]!=temp.H [j])
               break;
        }
        if(j>=DFA[i].count)
             temp.mark =DFA[i].mark;
    }
    return temp;
}
State move(State T,char s){
    State temp;
    temp.count =0;
    temp.mark =T.mark;
    int i,j=0,k=0;
    for(i=0;i<T.count;i++){
        j=0;
        while(j<n){
            if(E[j].start==T.H[i]&&E[j].c ==s){
                temp.H [temp.count ++]=E[j].end ;
            }
            j++;
        }
    }
    return temp;
}
//??????检查DFA中是否存在未被标记的状态,有则返回标号,否则返回-1;
int check_inDFA(){
    int i;
    for(i=0;i<numof_Dtran;i++){
        if(!useof_DFA[i])
           return i;
    }
    return -1;
}
//检查状态T是不是已经在DFA状态集中
bool check_whetherin_DFA(State T){
    int i,j;
    sort(T.H,T.H+T.count);
    for(i=0;i<numof_Dtran;i++){
        if(T.count!=DFA[i].count)
           continue;
        sort(DFA[i].H,DFA[i].H+DFA[i].count);
        for(j=0;j<DFA[i].count;j++){
            if(DFA[i].H[j]!=T.H[j])
               break;
        }
        if(j>=DFA[i].count)
            return true;
    }
    if(i>=numof_Dtran)
       return false;
    else
       return true;
}
void child_method(){
    int m,n;
    //初始化状态转换表
    for(m=0;m<100;m++){
        for(n=0;n<100;n++){
            Dtran[m][n]='#';
        }
    }
    for(m=0;m<100;m++)
      DFA[m].flag=-1;
    //确定初态
    State S0,U;
    S0.flag =0;
    S0.count =1;
    S0.H [0]=first;
    State T;
    T=closure(S0);
    T.mark=0;
    T.flag=0;
    DFA[numof_Dtran++]=T;
    memset(useof_DFA,0,sizeof(useof_DFA));
    //开始确定化,找新形成的DFA开始推导!
    int j=check_inDFA();
    int k;
    while(j!=-1){
        useof_DFA[j]=1;
        for(k=0;k<numof_char;k++){
            State g=move(DFA[j],alpha[k]);
            U=closure(g);
            if(!check_whetherin_DFA(U)){
                U.mark =numof_Dtran;
                DFA[numof_Dtran]=U;
                numof_Dtran++;
            }
            Dtran[DFA[j].mark][U.mark ]=alpha[k];
        }
        j=check_inDFA();
    }
/* */
}
void print(){
    int i,j;
    for(i=0;i<numof_Dtran;i++){
       cout<<i<<":";
       for(j=0;j<DFA[i].count;j++){
            cout<<DFA[i].H[j]<<" ";
        }
        if(DFA[i].flag==1)
          cout<<" 终态 ";
        if(DFA[i].flag==0)
          cout<<" 初态";
        cout<<endl;
    }
    cout<<endl;
    for(i=0;i<numof_Dtran;i++){
        for(j=0;j<numof_Dtran;j++){
            if(Dtran[i][j]!='#'){
                cout<<i<<"->"<<j<<" By "<<Dtran[i][j]<<endl;
            }    
        }
    }
    
}
int main(){
    input();
/*    cout<<"%%%%%%%%%%%%%%%"<<endl;
    for(int i=0;i<n;i++){
        cout<<DFA[i].flag<<"  ";
    }
    cout<<endl<<"***********"<<endl; */
    child_method();
    cout<<endl;
    print();
}

原文链接: https://www.cnblogs.com/wtx2333/p/12519838.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    NFA转DFA 子集构造法(Dev C++)

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/194514

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月12日 下午6:42
下一篇 2023年2月12日 下午6:43

相关推荐