zoukankan      html  css  js  c++  java
  • 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<<" 起点,终点,转换字符(’#‘表示空字符):" <<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();
    }

  • 相关阅读:
    SharePoint 2013 配置基于表单的身份认证
    SharePoint 2013 场解决方案包含第三方程序集
    SharePoint 2010 站点附加数据升级到SP2013
    SharePoint 2013 在母版页中插入WebPart
    SharePoint 2013 搭建负载均衡(NLB)
    SharePoint 部署解决方案Feature ID冲突
    SharePoint 2013 配置基于AD的Form认证
    SharePoint Server 2016 Update
    SharePoint 2013 为用户组自定义EventReceiver
    SharePoint 2013 JavaScript API 记录
  • 原文地址:https://www.cnblogs.com/wtx2333/p/12519838.html
Copyright © 2011-2022 走看看