hopcroft法的复杂度,他们说是nlogn,可是都没有严格的证明。难得找到一篇讲的详细点的论文,却又啰里啰唆的,不过那篇论文里面采用的是颜色树这个结构,有点意思。
前面的那个算法是n的平方复杂度,虽然这个复杂度计算都是建立在一些操作为单位时间操作的基础上。可是这些被认为的单位时间操作在我的实现中却有着平方复杂度,情何以堪,万恶的理论计算机科学家。
hopcroft实现的代码,太长了,还没写完。不过核心的子集分割已经完成了,剩下的就是分配节点及重新构建邻接表。明天再说吧。
1 #include "dfa_to_dfa.h" 2 pdfa_edge* rev_dfa_table;//作为dfa的反转表 3 int* belong_to;//这个是用来标记每个节点所在的群的标号 4 int** group_table;//这个是用来串联所有的群 5 int group_index;//这个用来表明使用了多少号的群 6 typedef struct _group_list 7 //这个结构用来把所有的当前在使用的群的标号串联起来 8 //这样就可以用来替代掉栈,而且也有利于遍历 9 { 10 struct _group_list* next; 11 int group_number; 12 }group_list,*pgroup_list; 13 pgroup_list group_list_begin=NULL;//这个是链表的专用头节点 14 void insert_group(int in_group_number)//将一个新的群号加入到群列表中,这里默认已经经过参数检查了 15 { 16 pgroup_list temp_list; 17 temp_list=malloc(sizeof(struct _group_list)); 18 temp_list->group_number=in_group_number; 19 temp_list->next=group_list_begin->next; 20 group_list_begin->next=temp_list; 21 } 22 23 24 void reverse_dfa(void)//构建反转表 25 { 26 int for_travel;//遍历变量 27 pdfa_edge temp_add;//作为反转表的增加边的变量 28 pdfa_edge temp_travel;//用来遍历原来的dfa表的邻接表的变量 29 int temp_dest;//增加边用的临时起始编号 30 rev_dfa_table=malloc(sizeof(struct _dfa_edge)*(dfa_node_number+1));//分配表的内存,注意加1 31 for(for_travel=1;for_travel<=dfa_node_number;for_travel++) 32 { 33 rev_dfa_table[for_travel]=NULL;//初始化为空 34 } 35 for(for_travel=1;for_travel<=dfa_node_number;for_travel++) 36 { 37 temp_travel=current_dfa_table[for_travel].begin; 38 while(temp_travel!=NULL) 39 { 40 temp_add=malloc(sizeof(struct _dfa_edge)); 41 temp_add->destination_number=for_travel; 42 temp_add->label=temp_travel->label; 43 temp_dest=temp_travel->destination_number; 44 temp_add->next=rev_dfa_table[temp_dest]; 45 rev_dfa_table[temp_dest]=temp_add; 46 } 47 }//现在已经完全构建好了反转表 48 } 49 50 51 52 typedef struct _rev_hash 53 { 54 int in_use;//0表示未使用,1表示正在使用,2表示已经删除 55 char* name; 56 int dfa_group_index; 57 }rev_hash; 58 rev_hash rev_hash_table[400]; 59 int insert_rev_hash(char* input_name,int dfa_group_pointer)//插入hash表 60 { 61 int for_i; 62 unsigned int result; 63 int counter; 64 int byte_of_table; 65 char* hash_name; 66 byte_of_table=(dfa_node_number+7)/8; 67 result=0; 68 for(for_i=0;for_i<byte_of_table;for_i++) 69 { 70 result+=(unsigned int) input_name[for_i]; 71 } 72 result=result%397; 73 counter=0; 74 while(counter<397) 75 { 76 if(rev_hash_table[result].in_use!=1) 77 { 78 rev_hash_table[result].dfa_group_index=dfa_group_pointer; 79 rev_hash_table[result].in_use=1; 80 hash_name=malloc(sizeof(char)*(byte_of_table+1)); 81 for(for_i=0;for_i<byte_of_table;for_i++) 82 { 83 hash_name[for_i]=input_name[for_i]; 84 } 85 hash_name[for_i]='