Re: [問題] 如何將文件內容順序天地顛倒

看板C_and_CPP作者 (髮箍)時間4年前 (2019/09/29 12:56), 4年前編輯推噓7(700)
留言7則, 7人參與, 4年前最新討論串2/2 (看更多)
※ 引述《InvincibleK (我是無敵的K)》之銘言: : 開發平台(Platform): (Ex: Win10, Linux, ...) : Linux : 編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出) : GCC : 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) : no : 問題(Question): : 如何將文件內容順序天地顛倒 : 餵入的資料(Input): : a1xxx : b2xxxxxx : a77oooooo : c3xxx : d4xxxx : e5xxxxxx : ... : z998ooooo : z999xxxx : 行數不定. : 預期的正確結果(Expected Output): : 請問要怎麼作到文件內容順序天地顛倒,變成: : z999xxxx : z998ooooo : ... : e5xxxxxx : d4xxxx : c3xxx : a77oooooo : b2xxxxxx : a1xxx : 然後存新檔? : 錯誤結果(Wrong Output): : 文件沒有天地顛倒 : 程式碼(Code):(請善用置底文網頁, 記得排版,禁止使用圖檔) : 未進行程式撰寫 : 補充說明(Supplement): : 本來單純只想用指令完成,沒有成功. 看標題以為是很複雜的處理; 不過這個題目雖然簡單卻是個練習寫 C++ 的好材料. 不知道原po 有否想過如果題目條件改一下, 程式碼 需要變動多少行才能達成需求呢? 1. 行輸出順序和原檔案相反, 且每行的內容反過來 2. 行輸出順序和原檔案相同, 每行的內容不變 3. 行輸出順序和原檔案相同, 但每行的內容反過來 最理想的答案是: 一行. 順便也推廣 C++ 其中一個核心精神: 只需要寫一份程式碼即可滿足不同需求 為了達成這個目標需要稍微做一點努力, 把原始碼整理成分工非常 明確的 3 個部分: 1. 處理輸入 2. 內部儲存 3. 處理輸出 行的順序我們可以透過抽換 2 的資料結構來完成, 這個很簡單, 就是使用 std::queue 和 std::stack 的分別. 為了節省空間只儲 存成對的迭代器 (iterator) 來標示行的開始和結束, 以下是簡單 的範例: https://bit.ly/2obN2oA 不過處理這種配接器 (adaptor) 最麻煩的是介面不一致: for (; !lines.empty(); lines.pop()) { const auto line = lines.top(); // will be front() if // we use std::queue } 這個時候就需要提供一組多載函式統一呼叫語法, 這樣就可以順利 將資料結構換成 std::queue: https://bit.ly/2nEPqDZ 像這個案例提供多載函式甚至是函式模版在 C++ 裡是再平常不過的 事情, 注意型別別名 (type alias) 的定義位置有些改動, 主要是 為了提供抽象化以及消除重複的程式碼. 至此抽換資料結構只需要 改一行. 另外要處理的是將字串內容反向印出, 也是對資料結構下手就好. 這時可以使用類別模版 std::reverse_iterator<Iter> 達成統一語 法的效果, 我們需要做的只是修改配接器的型別以及使用配接器的 地方: https://bit.ly/2m3GV5a 新增 create() 函式回傳成對的迭代器, 且在需要將字串反轉的情 況下回傳型別經包裝過的迭代器物件, 至此只需要改一行就能決定 印出的字串內容. 以上講的都是個別處理字串順序/內容的手法, 若要組合兩者可以用 policy-based design 來進一步改寫, 依功能面可分為: 1. line order policy 2. line content policy 各自定義需要的型別以及函式, 最後再用繼承將它們組裝起來, 變 成下面的程式碼: https://bit.ly/2ohwsDX 以上就是這個題目的一些變種提供給原po做練習, 其實還可以試試 其他更進階的版本: 1. 將字串依照長到短的順序印出 2. 將字串的大小寫反轉 ... -- P1389R0: Guidelines for Teaching C++ to Beginners https://bit.ly/2GvDWKb SG20 Education and Recommended Videos for Teaching C++ https://www.cjdb.com.au/sg20-and-videos -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 123.193.76.216 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1569732964.A.0F7.html

09/29 14:28, 4年前 , 1F
大推!
09/29 14:28, 1F

09/29 20:38, 4年前 , 2F
09/29 20:38, 2F

09/29 21:59, 4年前 , 3F
WOW
09/29 21:59, 3F
※ 編輯: poyenc (123.193.76.216 臺灣), 09/30/2019 01:50:24

09/30 09:50, 4年前 , 4F
09/30 09:50, 4F

10/01 00:35, 4年前 , 5F
10/01 00:35, 5F

10/03 16:40, 4年前 , 6F
push
10/03 16:40, 6F

10/21 02:04, 4年前 , 7F
好文!
10/21 02:04, 7F
文章代碼(AID): #1Ta3ba3t (C_and_CPP)
文章代碼(AID): #1Ta3ba3t (C_and_CPP)