看板 C_and_CPP 關於我們 聯絡資訊
檔案搜尋這問題有點老了,只是 聽說 通常 BFS 效率較 DFS 為佳, (有誤的話請指正),故拿來做 DFS / BFS 練習與比較。 練習中有另外一個衍生問題,請不吝指教。 ---------------- 衍生問題 : Macro Comment #define NO_OUTPUT #ifdef NO_OUTPUT #define printf // #define puts // #endif 上面這段 code 是因在 travel 時方便切換是否要輸出, 但我 "印象" 在以前有點年代的 C 書籍裡面似乎有提到, 不能將一些函式 re-define 成 comment, 妙的是手邊 vc / gcc 都可以吃這種東西, 不知這個是否合法? ---------------- 掃資料夾問題 先附上完整程式碼,http://codepad.org/SGj2ihfk 下面是概述流程,最後有提問( 效能上問題 ) DFS 上流程大概是 void DFS(const char * Path , const char * Filter) { char FullPath[MAX_PATH] ; /* sprintf(FullPath, "%s\\%s",Path,Filter); */ WIN32_FIND_DATA FileData; HANDLE hHandle = FindFirstFile(....); do{ /* sprintf(FullPath, "%s\\%s", Path, FileData.cFileName); 輸出 FileData.cFileName 若 FileData 是資料夾,且非 "." ".." 則進行 DFS(FullPath, Filter) */ }while(FindNextFile(....)); FindClose(hHandle); } BFS 小弟寫的流程大概如下 void BFS(const char* Path, const char* Filter) { char FullPath[MAX_PATH] ; /* sprintf(FullPath, "%s\\%s",Path,Filter */ WIN32_FIND_DATA FileData; HANDLE hHandle = FindFirstFile(....); char Folder[][MAX_PATH] ; /* 儲存 Path 底下之資料夾 */ do{ /* sprintf(FullPath, "%s\\%s", Path, FileData.cFileName); If ( IsFolder(FileData) ) FileData 加入 Folder; else 輸出 FullPath */ }while(FindNextFile(....)); for(i=0; i< FolderCnt; ++i) { 輸出 Folder[i] BFS(Folder, Filter) } FindClose(hHandle); } ------------- 為了測時,所以把輸出拿掉,避免 compiler opt 沒跑函式,所以沒加優化。 測試結果,BFS 反而較慢一點, 請問是否為我對 BFS / DFS 效能認知上有所誤失? 還是我 BFS 根本是寫錯的? 最後謝謝各位細心閱讀、耐心指導, 小弟感激不盡。 -- 就算把新鮮的肝拿回去,還是一樣寫碼到禿頭,加班到天亮。 你是不是想這麼做?是的話你就拿回去~ 拿啊!! 九世宅男 : 下輩子不要再讓我幹工程師了 ~ -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 180.177.76.161
kiedveian:看起來 DFS 和 BFS 好像反了? 11/02 15:46
linotwo:ret = printf(...); 編譯不過 11/02 15:49
EdisonX:疑!有反嗎?DFS 不是找到路就鑽進去嗎? 11/02 15:50
EdisonX:@@ 真的是寫反了. 11/02 15:50
EdisonX:@linotwo:編譯不過指的是連結 code 沒過嗎?這裡很順 @@ 11/02 15:52
EdisonX:方便給個錯誤訊息嗎?謝謝。 11/02 15:53
EdisonX:我看懂 linotwo 推文了,指的是 macro 那段, 謝謝提點 :) 11/02 15:55
kiedveian:實測結果DFS 334,BFS 322 11/02 16:04
linotwo:#define printf // 跟 #define printf 是同樣意思 11/02 16:07
kiedveian:另一筆測資DFS 1818,BFS 155 ,應該和測資有關 11/02 16:08
EdisonX:@linotwo : 謝謝提點,我再想一下有沒有辦法做 NO_OUTPUT. 11/02 16:12
EdisonX:@kiedeian : 謝謝您協助測試.解惑不少. :) 11/02 16:13
purpose:preprocessor 不認識 printf 是函式,只有 compiler 才懂 11/02 16:19
一開始真的完全忽略它是函式所帶來之 slide effect .
linotwo:http://codepad.org/NcX0GxQj 11/02 16:25
linotwo:要印出訊息的時候把 //#define DEBUG_MSG Uncomment 掉 11/02 16:28
kiedveian:fclose(stdout); //不知道會不會有bug, orz... 11/02 16:28
fclose(stdout) 在這篇文章應沒出現,想請教是否是我漏看了?
LPH66:comment 那個改成 #define printf(...) 0 這樣應該可行 11/02 16:57
LPH66:preprocessor 會把 printf 連括號裡面一堆全部換成 0 這樣 11/02 16:57
LPH66:不過話說我在 VC 好像類似的手法行不通 (那時是要拿掉 cerr) 11/02 16:58
LPH66:後來是用 #define cerr /##/ 才搞定 11/02 16:58
LPH66:已經忘記當初是怎麼想到的這個 hack 了 XD 11/02 16:59
maerdimer:char char *Path ... 11/02 17:08
已修正,謝謝指正。
linotwo:#define cerr /##/ 如果遇到 } 在同一行的話可能就不行了 11/02 17:57
感謝 LPH66、linotwo 給的建議,後來查一下網路,原來 macro 那段已不算小事, 再擴充下去大概會討論到 dprintf 吧,和原題意相差有點遠了, 或許再開主題做技術性的討論會較恰當。 另想請教的是 #define cerr /##/ 是什麼 ?? 初步猜測 /##/ 最後相黏會變 // 吧?是用在 C++ 部份嗎? cerr << "Hello, world!!" 謝謝各位熱心的賜教 ※ 編輯: EdisonX 來自: 180.177.76.161 (11/02 19:28)
kiedveian:搞錯問題了…不要理我…… 11/02 19:57
letoh:#define printf(...) 0 // 這樣寫可以嗎? 11/03 14:32
LPH66:唔, 過了好幾天才想到來回...我那個是 C++ 在用的沒錯 11/06 00:18
LPH66:如同上面所言直接 #define xxx // 在 preprocessor 裡會先把 11/06 00:18
LPH66:// 拿掉 所以就只是 #define xxx 這樣而已 因此才用/##/ 11/06 00:18
LPH66:讓 preprocessor 強迫把 cerr 代換成 // 兩個字再來處理 11/06 00:20
LPH66:所以要限制 debug 的東西全部要在同一行且沒有其他東西 11/06 00:21
EdisonX:謝謝 LPH66 細心回答 *^_^* 11/06 00:46