生成字首集合和字尾集合時,對環狀依賴的處理

2022-03-15 18:58:11 字數 2246 閱讀 5144

由於在生成前字尾的時候,我們需要將這個文法符號按照拓撲排序來排列生成順序,不過當語法裡面有環的時候,一般的拓撲排序就無效了,這個時候需要採取將乙個強聯通區域的點匯聚在一起,也就是生成壓縮略圖。課本上雖說強連通演算法是線性時間,但是不寫不知道,一寫嚇一跳,尼瑪都快四次複雜度了有木有。

這裡就貼一下生成強連通的**

1

void first_set_preprocess(void)//

這個函式是用來消除強聯通圖,把強聯通圖直接短接,最後生成乙個壓縮略圖240

for(for_i=1;for_i2;for_i++)

4156}57

//兩個臨時的圖都構建完成

58//

現在開始第一次dfs,為了保留各個節點的結束順序,我們剛好需要另外的乙個棧來儲存這些資訊

59//

因此我們需要兩個棧 來完成第一次遍歷

60//

第二次遍歷則需要哪些點已經完成了匯聚的資訊,因此我們需要乙個陣列來表示哪些點已經完成了匯聚

61//

同時第二次遍歷需要的是深度優先遍歷,這次我們可以復用原來的那個棧

62while(edge_number>0)63

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

86else

8791}92

else

93103

104}

105 new_first_graph[current_stack_top]=temp_first_node->next;

106 edge_number--;

107free(temp_first_node);

108}

109}

110111

112113

114 }//

現在全都按照結束序進入了第二個棧中

115//

現在開始第二遍深度優先遍歷,不過跟前面的那次遍歷有點不同。。。

116//

因為這次有了集合操作

117while(end_stack_index>0)//

只要棧裡還有元素

118137

else

138154

while(temp_after_node!=null)

155165

else

166172

}173

else

174179

}180 temp_after_node=rev_first_graph[parent_index];

181 temp_pre_node=null;

182while(temp_after_node!=null)

183193

else

194200

}201

else

202207

}208

for(for_i=1;for_i)

209216

else

217224

}225 }//

邊合併完成

226//

至此,鄰接表合併完成

227//

然後修改位置陣列

228for(for_i=1;for_i1;for_i++)

229234 }//

所屬的群索引標記完成

235 begin_stack_index--;

236}

237}

238}

239else

240244 }//

當前棧底可達的點都已經被合併為乙個群了

245 already_in_group[begin_stack[1]]=1

;246

}247

else

248251 }//

所有的群都已經生成完畢了

252 }

745 字首和字尾搜尋

給定多個words,words i 的權重為i。設計乙個類wordfilter實現函式wordfilter.f string prefix,string suffix 這個函式將返回具有字首prefix和字尾suffix的詞的最大權重。如果沒有這樣的詞,返回 1。例子 輸入 wordfilter.f...

中綴轉字尾和字首

中綴轉字尾 include using namespace std bool isoperator char ch intgetpriority char ch return level string postorder void trans string inorder s.pop else el...

ACM 線性 字首和 字尾和

題目描述 2015 年 uoi 馬上就要開始了,cssyz2015 資訊隊派出最強三位同學組成 宇宙隊 參加這次 acm 比賽,周老師想讓他們以最優的策略去完成比賽,於是,將題目分為 5 等,編號 1 到 5,數字越大,難度越大。對於每乙個同學,同一道題可能難度不一樣,現在,周老師想知道,如何安排學...