自动机

Code:
  1. #include <stdio.h>   
  2. #include <string.h>   
  3. #include <stdlib.h>   
  4. int st=1; //当前已用最大状态   
  5. int fi=0; //当前增加转换函数位置   
  6.   
  7. struct f   
  8.     {int from;   
  9.      char ch;   
  10.      int to;   
  11.     };   
  12. struct f nfaf[40];  //状态转换函数,数组   
  13. char r[80];   
  14.   
  15.   
  16.   
  17. void rtonfa(int from, char *r, int s,int t,int to);   
  18. int lowest(char *r,int s,int t);   
  19. int finish(char *r,int s,int t);   
  20.   
  21.     
  22.   
  23. main()   
  24. {int k,u;   
  25.     
  26.  scanf("%s",r); //输入正规式     
  27.  printf("/n正规式%s转换为NFA(0为初态,1为终态):/n",r);    
  28.     
  29.  u=strlen(r)-1;    
  30.  rtonfa(0,r,0,u,1);   //正规式R转换为非确定有穷自动机NFA,0是初态,1是终态,增加的状态从2开始递增编号,传递的是地址    
  31.     
  32.  for (k=0;k<fi;k++) printf("(%d,%c,%d)/n",nfaf[k].from,nfaf[k].ch,nfaf[k].to);  //NFA输出   
  33.  printf("/n");system("pause");   
  34.     
  35.  return 0;   
  36. }   
  37.   
  38.   
  39.   
  40. void rtonfa(int from, char *r, int s,int t,int to) //s正规式第一个字符位置,t正规式最后一个字符位置    
  41. {   
  42.  int j,x;   
  43.     
  44.  //if (s<=t)   //空串什么也不做    
  45.      if (s==t)   //只有一个字符,直接增加一个转换函数    
  46.         {nfaf[fi].from=from; nfaf[fi].ch=r[s]; nfaf[fi].to=to; fi++;}     
  47.      else { j=lowest(r,s,t);  //转换规则    
  48.             switch (r[j])   
  49.              {case '|': rtonfa(from,r,s,j-1,to);   
  50.                         rtonfa(from,r,j+1,t,to);   
  51.                         break;   
  52.               case '.': st++; x=st;    
  53.                         rtonfa(from,r,s,j-1,x);   
  54.                         rtonfa(x,r,j+1,t,to);   
  55.                         break;   
  56.               case '*': st++;   
  57.                         nfaf[fi].from=from;  nfaf[fi].ch='~'; nfaf[fi].to=st; fi++;    
  58.                         nfaf[fi].from=st;  nfaf[fi].ch='~'; nfaf[fi].to=to; fi++;   
  59.                         rtonfa(st,r,s,j-1,st);   
  60.                         break;   
  61.               case '(': rtonfa(from,r,s+1,t-1,to);//(去掉最外层括号)   
  62.                                        
  63.               }//switch         
  64.            }//else   
  65. }//rtonfa   
  66.   
  67. int lowest(char *r,int s,int t)  //返回正规式r最先转换的运算符所在的位置   
  68. int i=s, j, n;   
  69.   int id=-1; // 运算符优先级0'(' 1'*' 2'.' 3'|'     
  70.   while (i<=t)   
  71.      switch(r[i])   
  72.       {  case '|'if (id<3) {j=i;id=3;};i++; break;   
  73.          case '.'if (id<2) {j=i;id=2;};i++; break;   
  74.          case '*'if (id<1) {j=i;id=1;};i++; break;   
  75.          case '('if (id<0) {j=i;id=0;} n=finish(r,i,t);i+=n+1; break//i从对应')'后继续                         
  76.          default: i++;   
  77.       }   
  78.     return(j);   
  79. }   
  80.   
  81.   
  82.   
  83. int finish(char *r,int s,int t)   //返回'('对应')'间隔字符个数+1    
  84. {int v=s+1;   
  85.  int w;   
  86.  doif (r[v]=='(') {w=finish(r,v,t);v=v+w;}   
  87.      v++;   
  88.     }while (r[v]!=')') ;   
  89.   
  90.  return(v-s);   
  91. }  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值