c#二进制逆序方法详解

 更新时间:2013年10月03日 15:56:03   作者:  
这篇文章介绍了c#二进制逆序方法,有需要的朋友可以参考一下

原题

一个整数,可以表示为二进制的形式,请给出尽可能多的方法对二进制进行逆序操作。 例如:10000110 11011000的逆序为 00011011 01100001

分析

题目中说是一个整数,对它的二进制进行逆序。并不是一个01字符串,或者01的数组。那么我们该如何解决这个问题呢?方法还是比较多的,有的中规中矩、有的非常巧妙。我们要掌握中规中规的方法,见识更多的巧妙的方法。慢慢的,能够举一反三,在遇到新的问题时,能够有灵思妙想。

最直接的方法

直接的方法,很容易想到:有如下代码:

复制代码 代码如下:

直接的方法,很容易想到:有如下代码: int v = 111;
int r = v;
int s = 32;
for (; 0 != v; v >>= 1) {
    r <<= 1;
    r |= v & 1;
    s--;
}
r <<= s;
System.out.println(r);

代码比较好理解,取到v的最低位,作为r的最高位;v每取一次最低位,则右移一位;r每确定一位,则左移一位。同时记录移动了多少位,最终要补齐。

通过查表的方法

在遇到位操作的问题时,往往题目中限定了总的位数,比如这个题目,我们可以认为32位。这就给我们带来了一个以空间换时间的解决思路:查表法。位数是固定的,可以申请空间,存储预先计算好的结果,在计算其他的结果的时候,则查表即可。

32位相对于查表来讲,还是太大了。既然这样缩小范围,32个bit,也就是4个byte。每个byte 8bit,可以表示0-255的整数。可以通过申请256大小的数组,保存这256个整数,二进制逆序之后的整数。然后将一个32位的整数,划分为4个byte,每一个byte查表得到逆序的整数:r1,r2,r3,r4。按照r4r3r2r1顺序拼接二进制得到的结果就是最终的答案。

这是一个思路,大家可以进一步思考,尝试。

巧妙的方法

我们这里主要分析这个巧妙的方法,核心思想是:分治法。即:

•逆序32位分解为两个逆序16位的
•逆序16位分解为两个逆序8位的
•逆序8位分解为两个逆序4位的
•逆序4位分解为两个逆序2位的
最后一个2位的逆序,直接交换即可。也就是分治递归的终止条件。但是,在上面的过程中,还没有应用到位操作的技巧。根据动态规划的思想,我们可以自底向上的解决这个问题:

•每2位为一组,进行交换,完成2位逆序
•每4位为一组,前面2位与后面2位交换,完成4位逆序
•每8位为一组,前面4位和后面4为交换,完成8位的逆序
•每16位为一组,前面8位和后面8位交换,完成16位的逆序
2组16位的交换,完成32位的逆序

通过下面的例子,详解上面的过程,我们以16位为例:10000110 11011000

1 0 0 0 0 1 1 0 1 1 0 1 1 0 0 0
0 1 0 0 1 0 0 1 1 1 1 0 0 1 0 0
0 0 0 1 0 1 1 0 1 0 1 1 0 0 0 1
0 1 1 0 0 0 0 1 0 0 0 1 1 0 1 1
0 0 0 1 1 0 1 1 0 1 1 0 0 0 0 1

经过4步,逆序完成。推而广之,总的时间复杂度为O(logn),n是二进制的位数。这个方法可以推广到任意位。

示例代码如下:

int v =111;
v =((v >>1)&0x55555555)|((v &0x55555555)<<1);
v =((v >>2)&0x33333333)|((v &0x33333333)<<2);
v =((v >>4)&0x0F0F0F0F)|((v &0x0F0F0F0F)<<4);
v =((v >>8)&0x00FF00FF)|((v &0x00FF00FF)<<8);
v =( v >>16)|( v <<16);System.out.println(v);上面的思路理解了,代码不难理解。例如第二行,前边是取偶数位,后面是取奇数位,奇数位左移一位,偶数位右移一位,再取或,就是交换了奇数偶数位。也就是第一个步骤。

基于位运算的一些巧妙的方法有很多。大家可以自行研究,后面会和大家分享更多的面试题目。

【分析完毕】

相关文章

  • C# WPF ListBox 动态显示图片功能

    C# WPF ListBox 动态显示图片功能

    这篇文章主要介绍了C# WPF ListBox 动态显示图片,处理过程分为前台代码和后台代码,本文结合实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2023-08-08
  • C#如何操作Excel数据透视表

    C#如何操作Excel数据透视表

    这篇文章主要为大家详细介绍了C#如何操作Excel数据透视表, 创建透视表、设置行折叠、展开等操作,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-04-04
  • C#将Word或Excel文档转换为Html文件

    C#将Word或Excel文档转换为Html文件

    这篇文章介绍了C#将Word或Excel文档转换为Html文件的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • C#设置软件开机自动运行的方法(修改注册表)

    C#设置软件开机自动运行的方法(修改注册表)

    这篇文章主要介绍了C#设置软件开机自动运行的方法,通过简单修改注册表开机启动项实现软件的开机启动功能,非常简单实用,需要的朋友可以参考下
    2016-06-06
  • Unity实现简单的虚拟摇杆

    Unity实现简单的虚拟摇杆

    这篇文章主要为大家详细介绍了Unity实现简单的虚拟摇杆,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • C#通过反射创建自定义泛型

    C#通过反射创建自定义泛型

    这篇文章主要介绍了C#通过反射创建自定义泛型的方法,需要的朋友可以参考下
    2014-08-08
  • C#实现公式计算验证码的示例详解

    C#实现公式计算验证码的示例详解

    现在很多的平台已经不使用普通的数字、字母等验证码了,取而代之的是拼图类、选图类、旋转类或者计算类的验证码。本文将利用C#实现一个公式计算验证码,感兴趣的可以了解一下
    2022-10-10
  • C#数据结构之单链表(LinkList)实例详解

    C#数据结构之单链表(LinkList)实例详解

    这篇文章主要介绍了C#数据结构之单链表(LinkList)实现方法,结合实例形式较为详细的分析了单链表的原理、定义与C#具体实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-11-11
  • C#中如何使用redis

    C#中如何使用redis

    这篇文章主要介绍了C#中如何使用redis,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-07-07
  • C#数值转换-隐式数值转换表参考

    C#数值转换-隐式数值转换表参考

    隐式转换就是直接使用,比如可以把一个 byte 类型直接用在 int 上
    2013-04-04

最新评论