bit-wise reverse

lcf 2014-05-27 05:08:39
想起多年前听朋友叙述其面试题目,说怎么做一个bit-wise reverse (10101010 -> 01010101)在O(log(n))内解决 n = number of bits。没有任何其他限制。当时还记得的算法现在不记得了,也想不出来了(老了吧。。。),谁给提个醒儿呗
...全文
230 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
lcf 2014-05-28
  • 打赏
  • 举报
回复
多谢各位提醒!散分
俺是小王子 2014-05-27
  • 打赏
  • 举报
回复
引用 6 楼 vnvlyp 的回复:
[quote=引用 5 楼 benma378 的回复:] 我只是感觉有点抽象,通过那样的位运算就倒转过来了,实在没有看明白,能不能说一下数学原理
以i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;为例,你懂了这个就应该知道其他几行在干嘛 先看 | 或运算左边的(i & 0x55555555) << 1,首先0x55555555转换为二进制就是01010101010101010101010101010101,用 i 和这个数做&与运算,就是保留 i 所有奇数位,而把所有偶数位变为0,然后<<1是左移一位,左移后所有奇数位就左移到了偶数位上, 再看右边的(i >>> 1) & 0x55555555,首先>>>1是无符号右移,右移以后 i 所有偶数位就都移到了奇数位,然后和0x55555555就是刚才那个数进行&运算,那么同样保留所有奇数位,偶数位变0,注意现在的奇数位实际上是 i 的偶数位。 最后进行 | 或运算,把移动后的奇数位偶数位合并起来,所以最终效果就是原来奇数位的移动到偶数位上去了,原来偶数位的移动到奇数位去了。 0x33333333等是一样的原理,它的二进制为00110011001100110011001100110011,可以看到它的作用是每两位之间的移动, 0x0F0F0F0F则是00001111000011110000111100001111,每四位移动[/quote] 谢谢~
vnvlyp 2014-05-27
  • 打赏
  • 举报
回复
引用 5 楼 benma378 的回复:
我只是感觉有点抽象,通过那样的位运算就倒转过来了,实在没有看明白,能不能说一下数学原理
以i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;为例,你懂了这个就应该知道其他几行在干嘛 先看 | 或运算左边的(i & 0x55555555) << 1,首先0x55555555转换为二进制就是01010101010101010101010101010101,用 i 和这个数做&与运算,就是保留 i 所有奇数位,而把所有偶数位变为0,然后<<1是左移一位,左移后所有奇数位就左移到了偶数位上, 再看右边的(i >>> 1) & 0x55555555,首先>>>1是无符号右移,右移以后 i 所有偶数位就都移到了奇数位,然后和0x55555555就是刚才那个数进行&运算,那么同样保留所有奇数位,偶数位变0,注意现在的奇数位实际上是 i 的偶数位。 最后进行 | 或运算,把移动后的奇数位偶数位合并起来,所以最终效果就是原来奇数位的移动到偶数位上去了,原来偶数位的移动到奇数位去了。 0x33333333等是一样的原理,它的二进制为00110011001100110011001100110011,可以看到它的作用是每两位之间的移动, 0x0F0F0F0F则是00001111000011110000111100001111,每四位移动
俺是小王子 2014-05-27
  • 打赏
  • 举报
回复
引用 3 楼 fatg1988 的回复:
[quote=引用 2 楼 benma378 的回复:] [quote=引用 1 楼 fatg1988 的回复:]
/**
     * Returns the value obtained by reversing the order of the bits in the
     * two's complement binary representation of the specified <tt>int</tt>
     * value.
     *
     * @return the value obtained by reversing order of the bits in the
     *     specified <tt>int</tt> value.
     * @since 1.5
     */
    public static int reverse(int i) {
        // HD, Figure 7-1
	i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
	i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
	i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
	i = (i << 24) | ((i & 0xff00) << 8) |
	    ((i >>> 8) & 0xff00) | (i >>> 24);
	return i;
    }
jdk里面的分治法 01010101 00110011 00001111 这就是 3 5 F 能看明白吗?
我没看明白。。。。 能否详细解释一下。。。。 谢谢[/quote] 比如0101这个 i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555; 这是交换2位的 拆解成 (i & 0x5) << 1 | (i >>> 1) & 0x5; 这样你看清楚一点 完成的是2位的交换 [/quote] 效果上是这样的,但是我还是没有想明白这原理到底是什么? 感觉有点抽象?
引用 4 楼 vnvlyp 的回复:
1L正解,其实就是二分法 举个例子,要倒转11010101 只需要将其一分为二即1101和0101,分别倒转这两部分,然后交换位置就可以了 1101 倒转变成 1011 0101 倒转变成 1010 再交换位置得结果10101011 至于怎么倒转那两部分,同样的二分方法,最后到你只需要交换两位的时候就相当简单了 因为是二分法,所以复杂度Θ(log(n))
求解释,表示我还没有看出二分法。。。。 我只是感觉有点抽象,通过那样的位运算就倒转过来了,实在没有看明白,能不能说一下数学原理 谢谢! 或者有什么样的资料可以看看? 谢谢
vnvlyp 2014-05-27
  • 打赏
  • 举报
回复
1L正解,其实就是二分法 举个例子,要倒转11010101 只需要将其一分为二即1101和0101,分别倒转这两部分,然后交换位置就可以了 1101 倒转变成 1011 0101 倒转变成 1010 再交换位置得结果10101011 至于怎么倒转那两部分,同样的二分方法,最后到你只需要交换两位的时候就相当简单了 因为是二分法,所以复杂度Θ(log(n))
七神之光 2014-05-27
  • 打赏
  • 举报
回复
引用 2 楼 benma378 的回复:
[quote=引用 1 楼 fatg1988 的回复:]
/**
     * Returns the value obtained by reversing the order of the bits in the
     * two's complement binary representation of the specified <tt>int</tt>
     * value.
     *
     * @return the value obtained by reversing order of the bits in the
     *     specified <tt>int</tt> value.
     * @since 1.5
     */
    public static int reverse(int i) {
        // HD, Figure 7-1
	i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
	i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
	i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
	i = (i << 24) | ((i & 0xff00) << 8) |
	    ((i >>> 8) & 0xff00) | (i >>> 24);
	return i;
    }
jdk里面的分治法 01010101 00110011 00001111 这就是 3 5 F 能看明白吗?
我没看明白。。。。 能否详细解释一下。。。。 谢谢[/quote] 比如0101这个 i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555; 这是交换2位的 拆解成 (i & 0x5) << 1 | (i >>> 1) & 0x5; 这样你看清楚一点 完成的是2位的交换
俺是小王子 2014-05-27
  • 打赏
  • 举报
回复
引用 1 楼 fatg1988 的回复:
/**
     * Returns the value obtained by reversing the order of the bits in the
     * two's complement binary representation of the specified <tt>int</tt>
     * value.
     *
     * @return the value obtained by reversing order of the bits in the
     *     specified <tt>int</tt> value.
     * @since 1.5
     */
    public static int reverse(int i) {
        // HD, Figure 7-1
	i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
	i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
	i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
	i = (i << 24) | ((i & 0xff00) << 8) |
	    ((i >>> 8) & 0xff00) | (i >>> 24);
	return i;
    }
jdk里面的分治法 01010101 00110011 00001111 这就是 3 5 F 能看明白吗?
我没看明白。。。。 能否详细解释一下。。。。 谢谢
七神之光 2014-05-27
  • 打赏
  • 举报
回复
/**
     * Returns the value obtained by reversing the order of the bits in the
     * two's complement binary representation of the specified <tt>int</tt>
     * value.
     *
     * @return the value obtained by reversing order of the bits in the
     *     specified <tt>int</tt> value.
     * @since 1.5
     */
    public static int reverse(int i) {
        // HD, Figure 7-1
	i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
	i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
	i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
	i = (i << 24) | ((i & 0xff00) << 8) |
	    ((i >>> 8) & 0xff00) | (i >>> 24);
	return i;
    }
jdk里面的分治法 01010101 00110011 00001111 这就是 3 5 F 能看明白吗?

62,634

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧