#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");
}