• 生成前缀集合和后缀集合时,对环状依赖的处理


    由于在生成前后缀的时候,我们需要将这个文法符号按照拓扑排序来排列生成顺序,不过当语法里面有环的时候,一般的拓扑排序就无效了,这个时候需要采取将一个强联通区域的点汇聚在一起,也就是生成压缩图。课本上虽说强连通算法是线性时间,但是不写不知道,一写吓一跳,尼玛都快四次复杂度了有木有。

    这里就贴一下生成强连通的代码

      1 void first_set_preprocess(void)//这个函数是用来消除强联通图,把强联通图直接短接,最后生成一个压缩图
      2 {
      3     first_graph_node** rev_first_graph;//这个当作逆转图的入口,因为我们要生成这个逆转图
      4     first_graph_node** new_first_graph;//这个当作原来的图的拷贝,因为在拓扑排序时会毁掉原来的图
      5     pfirst_graph_node temp_first_node,temp_first_add;
      6     pfirst_graph_node temp_pre_node,temp_after_node;,temp_node
      7     int dest_symbol;
      8     int for_i,for_j;
      9     int edge_number;
     10     int* merge_to_list;
     11     int* merge_from_list;//这两个变量是用来合并邻接表使用的
     12     int* already_out_stack;//表示第一遍遍历的时候哪些点已经出栈了
     13     int* already_in_stack;//表示第一遍遍历的时候哪些点在当前栈中
     14     int* already_in_group;//表示哪些点已经在第二次遍历的过程中处理过了
     15     int graph_index;//这个变量用来遍历原来的图
     16     int parent_index;
     17     int* begin_stack;
     18     int* end_stack;
     19     int begin_stack_index;
     20     int end_stack_index;
     21     int current_stack_top;
     22     begin_stack_index=end_stack_index=0;
     23     edge_number=number_edge_first;
     24     rev_first_graph=malloc(sizeof(int)*(node_index+2));
     25     new_first_graph=malloc(sizeof(int)*(node_index+2));
     26     already_in_stack=malloc(sizeof(int)*(node_index+2));
     27     already_out_stack=malloc(sizeof(int)*(node_index+2));
     28     merge_to_list=malloc(sizeof(int)*(node_index+2));
     29     merge_from_list=malloc(sizeof(int)*(node_index+2));
     30     already_in_group=malloc(sizeof(int)*(node_index+2));
     31     for(for_i=1;for_i<node_index+2;for_i++)
     32     {
     33         rev_first_graph[for_i]=NULL;
     34         new_first_graph[for_i]=NULL;
     35         parent_set[for_i]=for_i;
     36         merge_to_list[for_i]=0;
     37         merge_from_list[for_i]=0;
     38 
     39     }
     40     for(for_i=1;for_i<node_index+2;for_i++)
     41     {
     42         temp_first_node=first_graph[for_i];
     43         while(temp_first_node!=NULL)
     44         {
     45             dest_symbol=temp_first_node->first_symbol;
     46             temp_first_add=malloc(sizeof(struct _first_graph_node));
     47             temp_first_add->next=rev_first_graph[dest_symbol];
     48             temp_first_add->first_symbol=for_i;
     49             rev_first_graph[dest_symbol]=temp_first_add;
     50             temp_first_add=malloc(sizeof(struct _first_graph_node));
     51             temp_first_add->first_symbol=dest_symbol;
     52             temp_first_add->next=new_first_next[for_i];
     53             new_first_next[for_i]=temp_first_add;
     54             temp_first_node=temp_first_node->next;
     55         }
     56     }
     57     //两个临时的图都构建完成
     58     //现在开始第一次dfs,为了保留各个节点的结束顺序,我们刚好需要另外的一个栈来保存这些信息
     59     //因此我们需要两个栈 来完成第一次遍历
     60     //第二次遍历则需要哪些点已经完成了汇聚的信息,因此我们需要一个数组来表示哪些点已经完成了汇聚
     61     //同时第二次遍历需要的是深度优先遍历,这次我们可以复用原来的那个栈
     62     while(edge_number>0)
     63     {
     64         for_i=0;
     65         while(new_first_graph[for_i]==NULL)
     66         {
     67             for_i++;
     68         }
     69         begin_stack_index=1;
     70         begin_stack[1]=for_i;
     71         already_in_stack[for_i]=1;
     72         while(begin_stack_index>0)
     73         {
     74             current_stack_top=begin_stack[begin_stack_index]
     75             temp_first_node=new_first_graph[current_stack_top];
     76             if(temp_first_node==NULL)
     77             {
     78                 if(begin_stack_index!=1)
     79                 {
     80                     end_stack_index++;
     81                     end_stack[end_stack_index]=current_stack_top;
     82                     already_out_stack[current_stack_top]=1;
     83                     already_in_stack[current_stack_top]=0;
     84                     begin_stack_index--;
     85                 }
     86                 else
     87                 {
     88                     already_in_stack[current_stack_top]=0;
     89                     begin_stack_index--;
     90                 }
     91             }
     92             else
     93             {
     94                 dest_symbol=temp_first_node->first_symbol;
     95                 if(already_out_stack[dest_symbol]!=1)
     96                 {
     97                     if(already_in_stack[dest_symbol]!=1)
     98                     {
     99                         begin_stack_index++;
    100                         begin_stack[begin_stack_index]=dest_symbol;
    101                         already_in_stack[dest_symbol]=1;
    102                     }
    103 
    104                 }
    105                 new_first_graph[current_stack_top]=temp_first_node->next;
    106                 edge_number--;
    107                 free(temp_first_node);
    108             }
    109         }
    110 
    111 
    112 
    113 
    114     }//现在全都按照结束序进入了第二个栈中
    115     //现在开始第二遍深度优先遍历,不过跟前面的那次遍历有点不同。。。
    116     //因为这次有了集合操作
    117     while(end_stack_index>0)//只要栈里还有元素
    118     {
    119         current_stack_top=end_stack[end_stack_index];
    120         end_stack_index--;
    121         if(already_in_group[current_stack_top]!=1)
    122         {
    123             begin_stack_index=1;
    124             begin_stack[begin_stack_index]=current_stack_top;
    125             while(rev_first_graph[begin_stack[1]]!=NULL)
    126             {
    127                 temp_node=rev_first_graph[begin_stack[begin_stack_index]];
    128                 dest_symbol=temp_node->first_symbol;
    129                 if(already_in_group[dest_symbol]!=1)
    130                 {
    131                     if(already_in_stack[dest_symbol]!=1)
    132                     {
    133                         begin_stack_index++;
    134                         begin_stack[begin_stack_index]=dest_symbol;
    135                         already_in_stack[dest_symbol]=1;
    136                     }
    137                     else
    138                     {
    139                         parent_index=parent_set[dest_symbol];//找到所在群的代表节点
    140                         while(begin_stack[begin_stack_index]!=parent_index)
    141                         {
    142                             //这里开始合并操作
    143                             current_stack_top=begin_stack[begin_stack_index];
    144                             temp_after_node=rev_first_graph[current_stack_top];
    145                             temp_pre_node=NULL;
    146                             //这里开始删除边了
    147                             //下面把这两个边里面邻接表中互相连接的边删除,并减少边的数目
    148                             //之后再把两者的邻接表合并,碰到重复的边也删除一个,并减少边的数目
    149                             for(for_i=0;for_i<node_index+2;for_i++)
    150                             {
    151                                 merge_to_list[for_i]=0;
    152                                 merge_from_list[for_i]=0;
    153                             }
    154                             while(temp_after_node!=NULL)
    155                             {
    156                                 if(parent_set[temp_after_node->first_symbol]==parent_index)
    157                                 {
    158                                     if(temp_pre_node==NULL)
    159                                     {
    160                                         rev_first_graph[current_graph_top]=temp_after_node->next;
    161                                         free(temp_after_node);
    162                                         temp_after_node=rev_first_graph[current_graph_top];
    163                                         edge_number--;
    164                                     }
    165                                     else
    166                                     {
    167                                         temp_pre_node->next=temp_after_node->next;
    168                                         free(temp_after_node);
    169                                         temp_after_node=temp_pre_node->next;
    170                                         edge_number--;
    171                                     }
    172                                 }
    173                                 else
    174                                 {
    175                                     merge_from_list[temp_after_node->first_symbol]=1;
    176                                     temp_pre_node=temp_after_node;
    177                                     temp_after_node=temp_after_node->next;
    178                                 }
    179                             }
    180                             temp_after_node=rev_first_graph[parent_index];
    181                             temp_pre_node=NULL;
    182                             while(temp_after_node!=NULL)
    183                             {
    184                                 if(parent_set[temp_after_node->first_symbol]==current_stack_top)
    185                                 {
    186                                     if(temp_pre_node==NULL)
    187                                     {
    188                                         rev_first_graph[current_graph_top]=temp_after_node->next;
    189                                         free(temp_after_node);
    190                                         temp_after_node=rev_first_graph[current_graph_top];
    191                                         edge_number--;
    192                                     }
    193                                     else
    194                                     {
    195                                         temp_pre_node->next=temp_after_node->next;
    196                                         free(temp_after_node);
    197                                         temp_after_node=temp_pre_node->next;
    198                                         edge_number--;
    199                                     }
    200                                 }
    201                                 else
    202                                 {
    203                                     merge_to_list[temp_after_node->first_symbol]=1;
    204                                     temp_pre_node=temp_after_node;
    205                                     temp_after_node=temp_after_node->next;
    206                                 }
    207                             }
    208                             for(for_i=1;for_i<node_index;for_i++)
    209                             {
    210                                 if(merge_to_list[for_i]==1)
    211                                 {
    212                                     if(merge_from_list[for_i]==1)
    213                                     {
    214                                         edge_number--;
    215                                     }
    216                                     else
    217                                     {
    218                                         temp_first_node_add=malloc(sizeof(strcut _first_graph_node));
    219                                         temp_first_node_add->first_symbol=for_i;
    220                                         temp_first_node_add->next=rev_first_graph[parent_index];
    221                                         rev_first_graph[parent_index]=temp_first_node_add;
    222                                         merge_to_list[for_i]=1;
    223                                     }
    224                                 }
    225                             }//边合并完成
    226                             //至此,邻接表合并完成
    227                             //然后修改位置数组
    228                             for(for_i=1;for_i<node_index+1;for_i++)
    229                             {
    230                                 if(parent_set[for_i]==current_stack_top)
    231                                 {
    232                                     parent_set[for_i]=parent_index;
    233                                 }
    234                             }//所属的群索引标记完成
    235                             begin_stack_index--;
    236                         }
    237                     }
    238                 }
    239                 else
    240                 {
    241                     begin_stack_index++;
    242                     begin_stack[begin_stack_index]=dest_symbol;
    243                 }
    244             }//当前栈底可达的点都已经被合并为一个群了
    245             already_in_group[begin_stack[1]]=1;
    246         }
    247         else
    248         {
    249             //神马都不干 
    250         }
    251     }//所有的群都已经生成完毕了
    252 }
  • 相关阅读:
    docker容器升级脚本
    Haproxy状态监控配置教程
    负载均衡之Haproxy配置详解(及httpd配置)
    升级代码脚本
    升级数据库脚本(加入事务)
    监控端口,新疆模拟用户登录脚本
    mongodb3.2系统性学习——3、update()操作
    Java Socket编程
    php错误级别设置
    php 用于绘图使用的颜色数组
  • 原文地址:https://www.cnblogs.com/huangfeidian/p/3175466.html
Copyright © 2020-2023  润新知