使用位黑客反转二进制数
Reversal of a binary number using bit hacks
有人可以解释一下二进制数是如何颠倒的吗?
unsigned rev = 0;
unsigned k = n;
while (k)
{
// add rightmost bit to rev
rev = (rev << 1) | (k & 1);
k = k >> 1; // drop last bit
cout<<"k val is "<<bitset<8>(k)<<endl;
cout<<"rev val is "<<{bitset<8>(rev)<<endl;
}
如果 n=9 则输出
K val 是 00000100 rev val 是 00000001 k val 是00000010 rev val 是00000010
k val 是00000001
rev val 是 00000100
k val 是 00000000
rev val 是 00001001
9 是回文
我指的是这里的问题2:http://www.techiedelight.com/bit-hacks-part-6-random-problems/
据我所知,如果"|"条件语句为真,则只执行第一个表达式。因此,这里的 rev<<1 仅在第一次执行循环时为假,而对于休息则不为假。因此,对于最后一个条件,rev 最终如何获得 1,因为 (k&1( 不会被执行。只有左移会被执行对吗?
一个可能有用的可视化是堆栈:假设您的数字n
由一堆二进制数字表示,最低有效数字位于堆栈的顶部。
然后,位反转的常见算法是迭代地从n
堆栈中逐个弹出数字,并将它们堆叠在另一个堆栈中(在您的情况下表示rev
(。
-
k = k >> 1;
从堆栈n
(在代码中重命名为k
(中弹出一个二进制数字 -
rev = (rev << 1) | (k & 1);
将二进制数字堆叠在k
堆栈的顶部。
在代码中,弹出/堆栈操作被颠倒以避免临时操作。
最后,只要n
堆栈中有数字,就应该重复 pop/stack 的此操作。这是因为while
条件只有k
,它测试k
是否为0(没有数字(。
PS:您有一些低级算法可以在位抖动黑客网站上执行位反转。这些算法旨在提高性能,因此可能不容易理解。
据我所知,如果第一个表达式对于"|"条件语句为真,则只执行第一个表达式。
| 运算符是按位的 OR:它的值是对其两个操作数的位模式的 OR 运算。它总是计算两个操作数,因为它需要它们的完整值。 示例:3 |5 是 7。
|| 是一个逻辑 OR:如果任一操作数(作为整个值(为 true,则为 true。如果第一个操作数为真,它不会评估第二个操作数。
代码使用 | 逐位 OR 一次构建一位答案。
变量rev
用0
初始化,它将包含结果。while
循环迭代,而作为输入的k
则剩下任何设定位。循环主体的第一个语句屏蔽了k
的最后一位并将其复制到rev
,在此过程中向左移动了一位(由 shift 运算符(。在循环迭代中,输入和输出都移动了 - 输入向右移动,输出向左移动。
- visual在c++中将十进制数转换为二进制数
- 二进制数之和(使用C样式字符串)
- 以 10 c++ 为基数显示 1024 位二进制数
- 二进制数和位标志'x'
- C++ 二进制数到整数值的数组
- 二进制数组中最大连续 1 的起始和结束索引,以 C++ 为单位
- dev如何在C++中比较二进制数
- 递归回溯打印长度为N的二进制数的所有组合,而不使用循环
- 向后打印二进制数
- 使用位黑客反转二进制数
- 添加两个二进制数(整数数组)
- 从 0 到 n 的二进制数,具有相同数量的字符/
- 我通过迭代加法将二进制数转换为十进制并检查单个字符(请参阅代码)的方法有什么问题?
- 所有测试用例都将小数点转换为二进制数
- 尝试将二进制数组转换为十六进制C++然后打印结果
- 如何缩放二进制数组以保留值
- 计数二进制数中连续1的数量
- 使用堆栈将十进制数转换为二进制数
- C++ 添加二进制数 - 分段错误
- 使用 for 循环更改二进制数>十进制数