【发布时间】:2019-09-15 20:36:43
【问题描述】:
我很好奇人们如何想出解决按位问题的方法。作为参考,我是本学期毕业的计算机工程专业的。我参加了谨慎的数学、数字逻辑设计、数字电子学和其他涉及使用布尔代数/按位运算的课程。但是,我仍然不太确定人们是如何提出按位问题的解决方案的。这是一个示例问题:
反转给定 32 位无符号整数的位。
输入:00000010100101000001111010011100
输出:00111001011110000010100101000000
这是 C++ 中的一个解决方案:
class Solution {
# define NUM_BITS 32
public:
uint32_t reverseBits(uint32_t n) {
uint32_t result = 0;
for (int i = 0; i < NUM_BITS; i++) {
if (n & (1 << i)) {
result |= (1 << ((NUM_BITS - 1) - i));
}
}
return result;
}
};
这实际上是一个 Leetcode 问题。在这个问题中,我知道为什么从 0 到 31 迭代的 for 循环是一个好主意,我们正在处理一个 32 位整数,但是条件语句和操作让我感到困惑:
if (n & (1 << i)) {
result |= (1 << ((NUM_BITS - 1) - i));
}
我了解这里发生了什么,但我不知道这是如何得出的。使用某种真值表?怎么会有人在面试中提出这个问题?如果有人拿了纸和铅笔,花了几个小时才发现这一点,我可以理解,但总的来说,我很好奇人们是如何想出这些解决方案的。
【问题讨论】:
-
一些辛苦的工作。
-
至少对我来说,在任何问题(不仅仅是针对按位运算)中,首先要以实用的方式思考解决方案——您将如何检查自己,然后尝试实施它使用我拥有的工具,例如此实例的按位运算。底线是它需要一些思考,而且人们的想法各不相同,所以对你来说更容易的事情对其他人来说更难,反之亦然。但练习总会让你变得更好。
-
它遍历位,每当找到 1 时,在镜像位置设置 1。就像写了一个伪代码一样。
-
我通常先“以人的身份”解决问题,然后再将其转化为代码。因此,如果有人对您说要反转输入的位并将它们写下来,那么您可能会逐位读取这些位并手动将输出向后写。这将成为您代码中的 for 循环。然后你需要弄清楚如何测试输入的每一位,这就是可怕的位移代码的来源。
-
坚持真的。我记得我自己发现了如何测试一个数字是否是 2 的幂。我花了整整一页的时间来写位并手动进行位运算才能最终弄清楚。在我完成之前我固执地拒绝查找它,当我查找它时,它就在那里:已经是一个 answer 在 SO 上。你只需要寻找模式。我仍然有兴趣找出从其他基础看素数是否有模式。那将是令人兴奋的
标签: c++ bit-manipulation bitwise-operators bit