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