Re: [問題] 請問我這個程式能用迴圈做嗎?

作者: poyenc (髮箍)   2020-04-03 17:01:08
※ 引述《IOP14759 (iop14759)》之銘言:
原文恕刪
C++ Community 有一個文化就是:
盡可能地使用現有工具, 如果沒現成的就自己造工具出來
注意上面這句話講的是自己造工具, 不是自己造程式. 通常在開發
C++ 程式時在做的就是把手中的工具兜成想要的樣子, STL 就是在
這文化薰陶下誕生的產物, 這個概念有點像是玩接水管的遊戲 (後
面會知道原因)
雖然原文在問能不能用迴圈做, 但我更想反問原 PO: 為什麼要用迴
圈做? 因為 C++ 很少在寫迴圈的. 這並不是什麼用遞迴取代迴圈的
論述, 而是寫迴圈這件事本身就是重工. 而且直接用迴圈實作可能
會讓你喪失分析問題的能力, 可以參考 Sean Parent 的分享:
GoingNative 2013: C++ Seasoning
https://channel9.msdn.com/Events/GoingNative/2013/Cpp-Seasoning
了解自己想做什麼事情, 才會知道要用什麼工具來達成目的. 原本
的問題可以拆解成幾個步驟:
1. 把整數轉換為數個 bit
2. 把這些 bit 轉換為對應的 '1' 或 '0' 字元
3. 保留特定數量的字元儲存/輸出
以上每個步驟都可以用標準函式庫現有的工具來實作, 這個在原文
下方小弟有提供簡單的範例. 主要概念是用 std::bitset 取得每個
位元, 用 std::string 儲存轉換好的字元, 再用
std::string_view 來顯示子字串:
範例 #1: https://wandbox.org/permlink/EX9D7pHtAtIjpPEU
在 C++ 裡需要注意物件的生命週期, 具有 value semantic 的型別
如 std::string 在操作時很像 primitive type, 所以很容易就會
創造許多不必要的臨時物件拖垮效能, 如此失去寫 C++ 的好處. 有
興趣探討的話可以參考 Herb Sutter 的 Exceptional C++ 系列書.
範例 #1 雖然簡單; 但因為有 raw loop, 本質上還存在以下問題:
1. 轉換邏輯和迴圈步進方向綁死
2. 高度相依於來源/目的容器型別及操作 (operator[], size())
3. 需要儲存中間的結果, 最後卻不會再用到
為了移除相依性, 我們需要導入迭代器 (iterator) 的觀念, 多了
這個抽象層, 我們可以用以下敘述來印出 std::bitset 的每個位元:
std::bitset<4> bits(10);
// print "0101"
std::copy(begin(bits), end(bits),
std::ostream_iterator<bool>(std::cout, ""));
不過很可惜 std::bitset 並沒有提供迭代器介面, 如果要沿用的話
我們必須手刻一個 adaptor 出來, 長相會是下面的樣子:
Iterator adaptor for random access range which has not
provided iterator interfaces (C++17)
https://bit.ly/2UDfKfN
我們需要偏特化 std::iterator_traits 才能和 STL Algorithm 無
縫套接, 而且因為要反向尋訪位元, 這個迭代器必須符合
LegacyBidirectionalIterator 概念 (concept). 做轉換的工作可
以附加在迭代器之上完成, 因為 Boost 裡已經有現成的直接套用即
可. 新的範例如下:
範例 #2: https://wandbox.org/permlink/LxQvdJOm12U9e44l
不同於範例 #1, 104 ~ 107 行等同於接水管的動作, 得利於模板 (
template) 的特性, 我們在設計水管的時候只需要盡可能地減少對
型別的依賴 (constraint), 就可以最大化復用性. 這個概念將在
C++20 後 Ranges library 趨於完整而逐步出現在其他函式庫實作
裡, 有興趣的話可以參考 Eric Niebler 的分享:
CppCon 2015: Ranges for the Standard Library
https://www.youtube.com/watch?v=mFUXNMfaciE
到這篇文的最後, 因為原 PO 的需求是要用 AnsiString 顯示部分
位元, 可以想想如何使用上面提到的工具兜出需要的功能? 另外,
如果問題改成: 將二進位表示法字串轉成整數. 你的程式碼又需要
做什麼修改呢?
作者: s4300026 (s4300026)   2020-04-05 11:08:00
作者: sarafciel (Cattuz)   2020-04-06 00:55:00
作者: flysonics (飛音)   2020-04-06 18:58:00

Links booklink

Contact Us: admin [ a t ] ucptt.com