- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- int st=1; //当前已用最大状态
- int fi=0; //当前增加转换函数位置
- struct f
- {int from;
- char ch;
- int to;
- };
- struct f nfaf[40]; //状态转换函数,数组
- char r[80];
- void rtonfa(int from, char *r, int s,int t,int to);
- int lowest(char *r,int s,int t);
- int finish(char *r,int s,int t);
- main()
- {int k,u;
- scanf("%s",r); //输入正规式
- printf("/n正规式%s转换为NFA(0为初态,1为终态):/n",r);
- u=strlen(r)-1;
- rtonfa(0,r,0,u,1); //正规式R转换为非确定有穷自动机NFA,0是初态,1是终态,增加的状态从2开始递增编号,传递的是地址
- for (k=0;k<fi;k++) printf("(%d,%c,%d)/n",nfaf[k].from,nfaf[k].ch,nfaf[k].to); //NFA输出
- printf("/n");system("pause");
- return 0;
- }
- void rtonfa(int from, char *r, int s,int t,int to) //s正规式第一个字符位置,t正规式最后一个字符位置
- {
- int j,x;
- //if (s<=t) //空串什么也不做
- if (s==t) //只有一个字符,直接增加一个转换函数
- {nfaf[fi].from=from; nfaf[fi].ch=r[s]; nfaf[fi].to=to; fi++;}
- else { j=lowest(r,s,t); //转换规则
- switch (r[j])
- {case '|': rtonfa(from,r,s,j-1,to);
- rtonfa(from,r,j+1,t,to);
- break;
- case '.': st++; x=st;
- rtonfa(from,r,s,j-1,x);
- rtonfa(x,r,j+1,t,to);
- break;
- case '*': st++;
- nfaf[fi].from=from; nfaf[fi].ch='~'; nfaf[fi].to=st; fi++;
- nfaf[fi].from=st; nfaf[fi].ch='~'; nfaf[fi].to=to; fi++;
- rtonfa(st,r,s,j-1,st);
- break;
- case '(': rtonfa(from,r,s+1,t-1,to);//(去掉最外层括号)
- }//switch
- }//else
- }//rtonfa
- int lowest(char *r,int s,int t) //返回正规式r最先转换的运算符所在的位置
- { int i=s, j, n;
- int id=-1; // 运算符优先级0'(' 1'*' 2'.' 3'|'
- while (i<=t)
- switch(r[i])
- { case '|': if (id<3) {j=i;id=3;};i++; break;
- case '.': if (id<2) {j=i;id=2;};i++; break;
- case '*': if (id<1) {j=i;id=1;};i++; break;
- case '(': if (id<0) {j=i;id=0;} n=finish(r,i,t);i+=n+1; break; //i从对应')'后继续
- default: i++;
- }
- return(j);
- }
- int finish(char *r,int s,int t) //返回'('对应')'间隔字符个数+1
- {int v=s+1;
- int w;
- do{ if (r[v]=='(') {w=finish(r,v,t);v=v+w;}
- v++;
- }while (r[v]!=')') ;
- return(v-s);
- }