采取的方法是hopcroft的填表法,详情见如下代码

  1. #include "nfa_to_dfa.h"
  2. int* dfa_diff_matrix;
  3.  
  4. int mini_dfa_number;//这个是最小化的 dfa表的索引
  5. typedef struct _min_dfa_node
  6. {
  7. pdfa_edge begin;
  8. int is_end;//记录是否是接受节点
  9. }min_dfa_node,*pmin_dfa_node;
  10. min_dfa_node mini_dfa_table[];//设定为100,其实也可以malloc一下,因为我们已经知道了有多少个节点了
  11. //为了偷懒,算了
  12. is_diff(int input_a,int input_b)//判断两个点是不是等价的程序,注意我们传参数的时候默认a比b大
  13. {
  14. int destination_a,destination_b;//临时的转换目标地址
  15. pdfa_edge temp_edge;//遍历邻接表
  16. char label_traverse;//用来遍历符号表
  17. int for_i;
  18. for(for_i=;for_i<alpha_size;for_i++)
  19. {
  20. label_traverse=mini_alpha_set[for_i];
  21. temp_edge=current_dfa_table[input_a].begin;
  22. while(temp_edge!=NULL&&temp_edge->label!=label_traverse)
  23. {
  24. temp_edge=temp_edge->next;
  25. }
  26. if(temp_edge==NULL)
  27. {
  28. destination_a=;
  29. }
  30. else
  31. {
  32. destination_a=temp_edge->dest_dfa_index;
  33. }
  34. temp_edge=current_dfa_table[input_b].begin;
  35. while(temp_edge!=NULL&&temp_edge->label!=label_traverse)
  36. {
  37. temp_edge=temp_edge->next;
  38. }
  39. if(temp_edge==NULL)
  40. {
  41. destination_b=;
  42. }
  43. else
  44. {
  45. destination_b=temp_edge->dest_dfa_index;
  46. }
  47. if(destination_a==destination_b)
  48. {
  49. //下一次吧
  50. }
  51. else
  52. {
  53. if(destination_a*destination_b==)
  54. {
  55. return ;
  56. }
  57. else
  58. {
  59. if( destination_a>destination_b)
  60. {
  61. if(dfa_diff_matrix[dfa_node_number*(input_a)+(input_b)]!=)//如果当前无法判别
  62. {
  63. if(is_diff(destination_a,destination_b))//如果可以判别
  64. {
  65. dfa_diff_matrix[dfa_node_number*(input_a)+(input_b)]=;
  66. return ;
  67. }
  68. else
  69. {
  70. //继续判别
  71. }
  72. }
  73. else
  74. {
  75. return ;
  76. }
  77. }
  78. else
  79. {
  80. if(dfa_diff_matrix[dfa_node_number*(input_b)+(input_a)]!=)//如果当前无法判别
  81. {
  82. if(is_diff(destination_b,destination_a))//如果可以判别
  83. {
  84. dfa_diff_matrix[dfa_node_number*(input_b)+(input_a)]=;
  85. return ;
  86. }
  87. else
  88. {
  89. //继续判别
  90. }
  91. }
  92. else
  93. {
  94. return ;
  95. }
  96. }
  97. }
  98. }
  99. }
  100. return ;
  101. }
  102. void diff_matrix(void)
  103. {
  104. int already_diff_number;//这个是用来判断有多少个点已经经过了等价性测试
  105. int for_i,for_j;
  106. dfa_diff_matrix=malloc(sizeof(int)*dfa_node_number*dfa_node_number);//分配这个节点
  107. for(for_i=;for_i<dfa_node_number;for_i++)
  108. {
  109. for(for_j=;for_j<dfa_node_number;for_j++)
  110. {
  111. dfa_diff_matrix[(for_i)*dfa_node_number+for_j]=;
  112. }
  113. }
  114. for(for_i=;for_i<dfa_node_number;for_i++)
  115. {
  116. for(for_j=;for_j<for_i;for_j++)//这里首先根据是否是接受节点来初始化矩阵
  117. {
  118. if(current_dfa_table[for_i+].is_end!=current_dfa_table[for_j+].is_end)
  119. {
  120. dfa_diff_matrix[(for_i)*dfa_node_number+for_j]=;
  121. }
  122. }
  123. }
  124. do{
  125. already_diff_number=;
  126. for(for_i=;for_i<dfa_node_number;for_i++)
  127. {
  128. for(for_j=;for_j<for_i;for_j++)
  129. {
  130. if(dfa_diff_matrix[(for_i)*dfa_node_number+for_j]!=)
  131. {
  132. if(is_diff(for_i,for_j)==)
  133. {
  134. dfa_diff_matrix[(for_i)*dfa_node_number+for_j]=;
  135. }
  136. }
  137. }
  138. }
  139. }while(already_diff_number!=);//如果本趟处理没有找到新的可分节点,就结束
  140. for(for_i=;for_i<dfa_node_number;for_i++)
  141. {
  142. for(for_j=;for_j<dfa_node_number;for_j++)
  143. {
  144. printf("%d ",dfa_diff_matrix[(for_i)*dfa_node_number+for_j]);
  145. }
  146. printf("\n");
  147. }
  148. }
  149. void minimize_dfa_matrix(void)//在已经构建好了dfa_diff_matrix后,开始群聚,并建图
  150. {
  151. //现在开始群聚
  152. int* already_in_group;//用来记录哪些点已经在群里面了
  153. int* temp_group;
  154. int* before_min_access;//这里来标注哪些节点已经通过了最简化dfa的转换
  155. int group_number=;//注意群号由0开始
  156. int* index_of_group;
  157. pdfa_edge temp_edge;//这个是用来重新建立最小化dfa的临时边
  158. pdfa_edge temp_add_edge;//这个是用来往最小dfa里面增加边的临时边
  159. int dest_group_number;//这个是在增加边的时候的目标编号
  160. int **group_set;
  161. int for_i,for_j;
  162. group_set=malloc(sizeof(int)*dfa_node_number);
  163. already_in_group=malloc(sizeof(int)*dfa_node_number);
  164. for(for_i=;for_i<dfa_node_number;for_i++)
  165. {
  166. already_in_group[for_i]=;
  167. *(group_set+for_i)=NULL;
  168. }
  169. for(for_i=;for_i<dfa_node_number-;for_i++)//聚集
  170. {
  171. if(already_in_group[for_i]==)
  172. {
  173. already_in_group[for_i]=;
  174. temp_group=malloc(sizeof(int)*dfa_node_number);
  175. *(group_set+group_number++)=temp_group;
  176. for(for_j=;for_j<dfa_node_number;for_j++)
  177. {
  178. temp_group[for_j]=;
  179. }//注意这里也需要考虑加减1的问题
  180. temp_group[for_i]=;
  181. for(for_j=for_i+;for_j<dfa_node_number;for_j++)
  182. {
  183. if(!dfa_diff_matrix[(for_j)*dfa_node_number+for_i])
  184. {
  185. temp_group[for_j]=;
  186. already_in_group[for_j]=;
  187. }
  188. }
  189. }
  190. }//现在已经完全都聚集为一团了
  191. mini_dfa_number=group_number;
  192. //现在再将节点和群的关系反转
  193. index_of_group=malloc(sizeof(int)*dfa_node_number);
  194. //这里又需要注意加减1的关系,由于这里dfa节点是从1标号的,而我们在index_of_group是从0标号的,要注意
  195. for(for_i=;for_i<dfa_node_number;for_i++)
  196. {
  197. index_of_group[for_i]=;
  198. }
  199. for_i=;
  200. while(*(group_set+for_i)!=NULL)//前面开了一个索引数组,现在来赋值,这样就可以直接得到某个节点所在的群号
  201. {
  202. for(for_j=;for_j<dfa_node_number;for_j++)
  203. {
  204. if(*(*(group_set+for_i)+for_j)==)
  205. {
  206. index_of_group[for_j]=for_i;
  207. }
  208. }
  209. for_i++;
  210. }//现在关系已经翻转了
  211. //下一步就是利用这个点与群的关系来新建立一个dfa图
  212. //这里的群号就是节点的编号,由于每个群里面的节点都是等价的,所以只需要找一个节点就行了
  213. for(for_i=;for_i<=group_number;for_i++)//这里的for_i是用来表示最小dfa图的标号,所以从1开始
  214. {
  215. //对每一个群进行遍历
  216. mini_dfa_table[for_i].begin=NULL;
  217. mini_dfa_table[for_i].is_end=;
  218. for_j=;
  219. while(*(*(group_set+for_i-)+for_j)!=)//由于group是从0开始标号的,所以要减去1
  220. {
  221. for_j++;
  222. }//找到这个群里面一个节点,注意加减一问题,少犯错误啊,1号节点存储在0号位置上
  223. if(current_dfa_table[for_j+].is_end)
  224. {
  225. mini_dfa_table[for_i].is_end=;//标记为结束节点
  226. }
  227. temp_edge=current_dfa_table[for_j+].begin;
  228. while(temp_edge!=NULL)//重新建设邻接表
  229. {
  230. temp_add_edge=malloc(sizeof(struct _dfa_edge));
  231. temp_add_edge->label=temp_edge->label;
  232. temp_add_edge->next=mini_dfa_table[for_i].begin;
  233. dest_group_number=index_of_group[temp_edge->dest_dfa_index-]+;//特别要注意这里的加一和减一
  234. //由于temp_edge->dest_dfa_node是从1开始标号的,而index_of_group是从0开始标号的,所以我们要减一
  235. //同样,又由于最后的最简化dfa的图是从1开始标号的,所以我们要加1;
  236. temp_add_edge->dest_dfa_index=dest_group_number;
  237. mini_dfa_table[for_i].begin=temp_add_edge;
  238. temp_edge=temp_edge->next;
  239. }
  240. //本群的邻接表构建完成
  241. }//所有群的邻接表构建完成
  242. }
  243. void show_mini_dfa(void)//输出图
  244. {
  245. int for_i;
  246. pdfa_edge temp_dfa_edge;
  247. number_of_end_dfa=;
  248. for(for_i=;for_i<=mini_dfa_number;for_i++)
  249. {
  250. if(mini_dfa_table[for_i].is_end==)
  251. {
  252. printf("this node is an destination node ,index is %d\n",for_i);
  253. }
  254. temp_dfa_edge=mini_dfa_table[for_i].begin;
  255. while(temp_dfa_edge!=NULL)
  256. {
  257. printf("there is an dfa edge from %d to %d with label %c\n",for_i,temp_dfa_edge->dest_dfa_index,temp_dfa_edge->label);
  258. temp_dfa_edge=temp_dfa_edge->next;
  259. }
  260. }
  261. printf("the minimized dfa is completed\n");
  262. }

dfa最小化,终于完成了。的更多相关文章

  1. DFA 最小化

    NDFA.εNDFA 确定化的细节这里就不总结了,这里说一说DFA最小化的算法. 关于DFA最小化,

  2. dfa最小化,修正了上个版本的一些错误。

    上个版本测试的时候,只用了两个非常简单的测试用例,所以好多情况有问题却没有测试出来 bug1:在生成diff_matrix的时候,循环变量少循环了一次,导致最后一个节点在如果无法与其他点合并的情况下, ...

  3. 编译原理中DFA最小化

    关于编译原理最小化的操作,专业术语请移步至:http://www.360doc.com/content/18/0601/21/11962419_758841916.shtml 这里只是记录一下个人的理 ...

  4. 第九次作业——DFA最小化,语法分析初步

    老师:MissDu 提交作业 1.将DFA最小化:教材P65 第9题 答: 2.构造以下文法相应的最小的DFA S→ 0A|1B A→ 1S|1 B→0S|0 3.自上而下语法分析,回溯产生的原因是 ...

  5. DFA最小化,语法分析初步

    1.将DFA最小化:教材P65 第9题 2.构造以下文法相应的最小的DFA S→ 0A|1B A→ 1S|1 B→0S|0 语言:(01 | 10)*(01 | 10) 自动机图: DFA状态转换矩阵 ...

  6. 编译原理之DFA最小化,语法分析初步

    1.将DFA最小化: 状态转换图: 识别语言:b*ac*(da)*bb* 2.构造以下文法相应的最小的DFA S→ 0A|1B A→ 1S|1 B→0S|0 (1)正规式: S -> 0(1S+ ...

  7. 第九次作业 DFA最小化,语法分析初步

    1.将DFA最小化:教材P65 第9题 Ⅰ {1,2,3,4,5} {6,7} {1,2}b={1,2,3,4,5} 3,4}b={5} {6,7} Ⅱ {1,2}{3,4}{5} {6,7} 2.构 ...

  8. 作业九——DFA最小化

    1.将DFA最小化:教材P65 第9题 I {1, 2, 3, 4, 5} {6, 7} {1, 2}b->{1, 2, 3, 4, 5} {3, 4}b->{6, 7} {5}b-> ...

  9. 编译原理:DFA最小化,语法分析初步

    1.将DFA最小化:教材P65 第9题   解析: 2.构造以下文法相应的最小的DFA S→ 0A|1B A→ 1S|1 B→0S|0 解析: S→ 0A|1B →S → 0(1S|1)|1(0S|0 ...

  10. 第九次-DFA最小化,语法分析初步

    1.将DFA最小化:教材P65 第9题 2.构造以下文法相应的最小的DFA S→ 0A|1B A→ 1S|1 B→0S|0 3.自上而下语法分析,回溯产生的原因是什么? 4.P100 练习4,反复提取 ...

随机推荐

  1. stl map高效遍历删除的方法 [转]

    for(:iter!=mapStudent.end():) {      if((iter->second)>=aa)      {          //满足删除条件,删除当前结点,并指 ...

  2. C#自定义控件背景色透明的方法

    I struggled for ages with the problem of having controls show through a control that was painted on ...

  3. CloudStack采用spring加载bean(cloud-framework-spring-module模块)

    CloudStackContextLoaderListener /* * Licensed to the Apache Software Foundation (ASF) under one * or ...

  4. HDU 2066 一个人的旅行 - from lanshui_Yang

    Problem Description 虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途中 会遇见很多人(白马王子,^0^),很多事,还能丰 ...

  5. cmd下运行PowerShell命令

    PowerShell -Command "& {Get-EventLog -LogName security}"

  6. PCA和白化练习之处理图像

    第一步:下载pca_exercise.zip,里面包含有图像数据144*10000,每一列代表一幅12*12的图像块,首先随见展示200幅: 第二步:0均值处理,确保数据均值为0或者接近0 第三步:执 ...

  7. DedeCMS调用多说评论系统遇到的一些问题

    最近前端笔记加入了多说的评论,因为自带的评论太渣了.过程不是很顺利,把遇到的问题和大家分享下.我用的dedecms,所以使用的是dede的多说评论模块.效果图: 多说官方下载:http://dev.d ...

  8. NopCommerce使用Autofac实现依赖注入

    NopCommerce的依赖注入是用的AutoFac组件,这个组件在nuget可以获取,而IOC反转控制常见的实现手段之一就是DI依赖注入,而依赖注入的方式通常有:接口注入.Setter注入和构造函数 ...

  9. Golang学习 - io/ioutil 包

    ------------------------------------------------------------ // Discard 是一个 io.Writer 接口,调用它的 Write ...

  10. 遍历List remove方法,雨露均沾

    /** * 要求:去掉List中为 0 的元素 */ //创建数组和空List Integer[] ars = {1,0,0,0,5,0,8,9,0,0,0,65,3,0,0}; List<In ...