自动机确定化

#include<stdio.h>
#include<windows.h>

typedef struct{
    int state[100];  //状态集合
    int snum=0;       //状态个数
    int N=0;          //符号个数
    //int index;      //自身编号
    int index[100];        //符号      
    int to[100][100];    //状态转移到的集合

}ND;
ND NFA[100],DFA[100];
typedef struct{
    int beg[100];//开始状态
    int end[100];//结束状态
    int smnm;//字符个数
    int statenm;//状态个数
    int dfanm=0;
    int nnm;
    int ssm[100]={-1};
}declare;
declare DL;
int findnfa(int state,int n){
    for(int i=0;i<n;i++)
        if(NFA[i].state[0]==state)return i;
    return n; 
}
int length(int a[]){
    int i=0;
    while(a[i]!=-1)i++;
    return i;

}
void NTODREAD(){
    FILE *fp;
    char name[20];
    scanf("%s",&name);
    if((fp=fopen(name,"r"))==NULL)exit(0);
    while(!feof(fp)){
        fscanf(fp,"%d",&DL.statenm);
        for(int i=0;i<DL.statenm;i++)
            {NFA[i].index[1]=-1;
             NFA[i].to[0][0]=-1;
            }
        fscanf(fp,"%d",&DL.smnm);
        int flag,x,i=0;
        NFA[i].N=0;NFA[i].snum=0;
        fscanf(fp,"%d",&x);
        flag=x;
        while(x!=-1){
            int ii=findnfa(x,i);
            if(ii==i)i++;
            NFA[ii].state[0]=x;
            fscanf(fp,"%d",&x);
            NFA[ii].index[NFA[ii].N++]=x;
            int k=0;
            fscanf(fp,"%d",&x);
            while(x!=-1){
                NFA[ii].to[NFA[ii].index[NFA[ii].N-1]][k++]=x;
                fscanf(fp,"%d",&x);
            }
            NFA[ii].to[NFA[ii].index[NFA[ii].N-1]][k++]=-1;
            fscanf(fp,"%d",&x);
            
        }
        DL.nnm=i;
        fscanf(fp,"%d",&x);
        i=0;
        while(x!=-1){
            DL.beg[i++]=x;
            fscanf(fp,"%d",&x);
        }
        DL.beg[i]=-1;
        fscanf(fp,"%d",&x);
        i=0;
        while(x!=-1){
            DL.end[i++]=x;
            fscanf(fp,"%d",&x);
        }
        DL.end[i]=-1;
    }
    fclose(fp);
    if(DL.statenm!=DL.nnm){
        for(int i=0;i<DL.nnm;i++){
            for(int j=0;j<NFA[i].N;j++){
                for(int k=0;k<length(NFA[i].to[NFA[i].index[j]]);k++)
                    {
                        int l=findnfa(NFA[i].to[NFA[i].index[j]][k],DL.nnm);
                        if(l==DL.nnm){
                            DL.nnm++;
                            
                            NFA[l].state[0]=NFA[i].to[NFA[i].index[j]][k];
                            NFA[l].N=0;
                            NFA[l].index[0]=-1;
                            for(int m=0;m<DL.smnm;m++)
                                NFA[l].to[DL.ssm[m]][0]=-1;
                        }
                    }
            }

        }


    }
    for(int i=0;i<DL.statenm;i++)
        NFA[i].index[NFA[i].N]=-1;
    //NFA[10].index[0]=-1;    

}
void NTODWRITE(){
    printf("NFA:\n");
    for(int i=0;i<DL.statenm;i++){
        for(int j=0;j<NFA[i].N;j++)
            {printf("%d %d ",NFA[i].state[0],NFA[i].index[j]);
             int k=0;
             while(NFA[i].to[NFA[i].index[j]][k]!=-1){
                 printf("%d ",NFA[i].to[NFA[i].index[j]][k]);
                 k++;
             }   
             printf("\n");
            }
        printf("\n");
    }
}

int isin(int a[],int x){
    int le=length(a);
    for(int i=0;i<le;i++)
        if(a[i]==x)return 1;
    return 0;
}
int nfainfo(int a){
    for(int i=0;i<DL.statenm;i++)
        if(NFA[i].state[0]==a)return i;
    return -1;
}
void sort(int a[],int left,int right){
	int i,j,temp,t;
	if(left>right){
		return ;
	}
	temp = a[left];
	i  = left;
	j = right;
	while(i!=j){
		while(a[j]>=temp&&i<j)
			j--;
		while(a[i]<=temp&&i<j)
			i++;
		if(i<j){
			t = a[i];
			a[i] = a[j];
			a[j] = t;
		}
	}
	a[left] = a[i];
	a[i] = temp;
	sort(a,left,i-1);
	sort(a,i+1,right);
}
int comp(int a[],int b[]){
    int a1[100],b1[100];
    int la=length(a),lb=length(b);
    if((la-lb)!=0)return 0;
    for(int i=0;i<la;i++){
        a1[i]=a[i];
        b1[i]=b[i];
    }
    sort(a1,0,la-1);
    sort(b1,0,la-1);
    for(int i=0;i<la;i++)
        if((a1[i]-b1[i])!=0)return 0;
    return 1;
}
int FINDDFA(int a[]){
    for(int i=0;i<DL.dfanm;i++)
        if(comp(a,DFA[i].state))return i;
    return -1;


}
void FINDSYM(){
    int t=0;
    for(int i=0;i<DL.statenm;i++){
        for(int j=0;j<NFA[i].N;j++)
            if(isin(DL.ssm,NFA[i].index[j])==0&&NFA[i].index[j]!=0)
                {DL.ssm[t++]=NFA[i].index[j];DL.ssm[t]=-1;}
    }


}
void FIND0(int a[]){
    int c[100],la=length(a),lc=la;
    //printf("la=%d\n",la);
    for(int i=0;i<=la;i++)
        c[i]=a[i];
    for(int i=0;i<la;i++){
        int t=nfainfo(a[i]);
        //printf("i=%d\n",i);
        //printf("t=%d\n",t);
        if(t!=-1){
            if(isin(NFA[t].index,0)){
                int j=0;
                while(NFA[t].to[0][j]!=-1)
                    {
                        if(isin(a,NFA[t].to[0][j])==0)a[la++]=NFA[t].to[0][j];
                        j++;
                        //printf("j=%d\n",j);
                    }

            }

        }

    }
    a[la]=-1;

}
void NTOD(){
    
    printf("DFA:\n");
    int temp[100];
    int i=0;
    while(DL.beg[i]!=-1){
        DFA[0].state[i]=DL.beg[i];
        i++;
    }
    
    //printf("i=%d\n",i);
    DFA[0].state[i]=-1;
    DL.dfanm++;
    FIND0(DFA[0].state);
    FINDSYM();
    //printf("length=%d\n",length(DFA[0].state));
    //int a[]={0,1,2,4,7,-1};
    //printf("finddfa=%d\n",FINDDFA(a));
    /*
        i=0;
        while(DFA[0].state[i]!=-1){
        printf("%d ",DFA[0].state[i]);
        i++;
    }*/
    /*FINDSYM();
    for(int i=0;i<length(DL.ssm);i++)
        printf("%d ",DL.ssm[i]);
        //输出字符集
        */
    for(int i=0;i<DL.dfanm;i++){
        //printf("i=%d\n",i);
        int len=length(DFA[i].state);
        int temp[100]={-1},tpi=0;
        DFA[i].index[length(DL.ssm)]=-1;
        for(int k=0;k<length(DL.ssm);k++){
            tpi=0;
            //printf("k=%d\n",k);
            DFA[i].index[k]=DL.ssm[k];
            
            for(int j=0;j<len;j++){
                int info=nfainfo(DFA[i].state[j]);
                if(isin(NFA[info].index,0)){
                    int ni=0;
                    while(NFA[info].to[0][ni]!=-1){
                        if(isin(temp,NFA[info].to[0][ni])==0)
                            {temp[tpi++]=NFA[info].to[0][ni];
                                temp[tpi]=-1;
                            }
                        ni++;
                        //printf("ni=%d\n",ni);
                    }
                }
                if(isin(NFA[info].index,DL.ssm[k])){
                    int ni=0;
                    while(NFA[info].to[DL.ssm[k]][ni]!=-1){
                        if(isin(temp,NFA[info].to[DL.ssm[k]][ni])==0)
                            {temp[tpi++]=NFA[info].to[DL.ssm[k]][ni]; temp[tpi]=-1;}
                        ni++;
                       // printf("ni=%d\n",ni);
                    }
                }
               //FIND0(temp);
            }
             FIND0(temp);
                if(length(temp)==0){
                    DFA[i].to[DL.ssm[k]][0]=-1;
                }
                else{
                    int ftp=FINDDFA(temp);
                    if(ftp!=-1){
                        DFA[i].to[DL.ssm[k]][0]=ftp;
                        DFA[i].to[DL.ssm[k]][1]=-1;
                        temp[0]=-1;
                    }
                    else {
                        DFA[i].to[DL.ssm[k]][0]=DL.dfanm;
                        DFA[i].to[DL.ssm[k]][1]=-1;
                        for(int i=0;i<=length(temp);i++)
                            {DFA[DL.dfanm].state[i]=temp[i];
                             DFA[DL.dfanm].state[i+1]=-1;
                            }
                        temp[0]=-1;
                        DL.dfanm++;
                    }
                }
        }


    }

    
    
}
void DFAWRITE(){
    printf("状态个数:%d\n",DL.dfanm);
    printf("字符表个数:%d\n状态转换:\n",length(DL.ssm));
    for(int i=0;i<DL.dfanm;i++){
        for(int k=0;k<length(DL.ssm);k++){
            if(DFA[i].to[DL.ssm[k]][0]!=-1){
                printf("(%d,%d)->%d\n",i,DL.ssm[k],DFA[i].to[DL.ssm[k]][0]);
            }
        }

    }
    int kaishi[100]={-1},jieshu[100]={-1},ks=0,js=0;
    for(int i=0;i<DL.dfanm;i++){
        for(int j=0;j<length(DFA[i].state);j++){
            if(isin(DL.beg,DFA[i].state[j])){
                kaishi[ks++]=i;kaishi[ks]=-1;
            }
            if(isin(DL.end,DFA[i].state[j])){
                jieshu[js++]=i;jieshu[js]=-1;
            }
        }
    }
    printf("开始集合:{");
    for(int i=0;i<length(kaishi);i++){
        if(i!=length(kaishi)-1)printf("%d,",kaishi[i]);
        else printf("%d}\n",kaishi[i]);
    }
    printf("结束集合:{");
    for(int i=0;i<length(jieshu);i++){
        if(i!=length(jieshu)-1)printf("%d,",jieshu[i]);
        else printf("%d}\n",jieshu[i]);
    }
}
int main(){
    NTODREAD(); NTODWRITE();//输入NFA
    NTOD();                 //NFA转换DFA
    DFAWRITE();             //输出DFA
    system("pause");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值