zoukankan      html  css  js  c++  java
  • 算法——字节高低位交换

    转自:http://blog.csdn.net/syzcch/article/details/8149706

    问题

    对一个字节数据,逐个交换其高低位,例如11010001,经过0-7,1-6,2-5,3-4对应位的交换,变成10001011 。

    解决思路

    对于该问题,我们最先想到的是对原字节通过移位操作来逐位处理,使用另一个变量来存储交换后的结果。这种解决方案处理起来思路清晰,编写代码应该不难。


    下面是该思路对应的代码:

    [cpp] view plain copy
    1. unsigned char shift_fun1(unsigned char data)  
    2. {  
    3.     unsigned char i;  
    4.     unsigned char tmp=0x00;  
    5.   
    6.     for(i=0;i<8;i++)  
    7.     {  
    8.         tmp=((data>>i)&0x01)|tmp;  
    9.         if(i<7)  
    10.             tmp=tmp<<1;  
    11.     }  
    12.   
    13.     printf("  after shift fun1 data=%x  ",tmp);  
    14.   
    15.     return tmp;  
    16.       
    17. }  

    上述代码实现起来不难,而且效率还是比较高的。但是还有比这更简洁的解决方法,在嵌入式开发中遇到交换字节位的问题时通常使用蝶式交换法和查表法来实现。查表法顾名思义即将一些值存到内存中,需要计算时查表即可,但是也会占用额外的存储空间。这里主要再介绍一下蝶式交换法。

    所谓的蝶式交换是这样的:

    [cpp] view plain copy
    1. data=(data<<4)|(data>>4);  
    2. data=((data<<2)&0xcc)|((data>>2)&0x33);  
    3. data=((data<<1)&0xaa)|((data>>1)&0x55);  

    我们可以做一下执行演算:

    假设原始位序列为  0 1 0 1  1 0 0 1  

    data=(data<<4)|(data>>4);之后序列为  1 0 0 1  0 1 0 1

    data=((data<<2)&0xcc)|((data>>2)&0x33);  之后序列为  0 1 1 0  0 1 0 1

    data=((data<<1)&0xaa)|((data>>1)&0x55);  之后序列为 1 0 0 1  1 0 1 0


    更抽象的来说 原始位为 1 2 3 4  5 6 7 8

    data=(data<<4)|(data>>4); 之后位序为  5 6 7 8  1 2 3 4

    data=((data<<2)&0xcc)|((data>>2)&0x33);   之后位序为  7 8 5 6  3 4 1 2

    data=((data<<1)&0xaa)|((data>>1)&0x55);   之后位序为  8 7 6 5  4 3 2 1  

    由此完成了整个位的逆序转换,下面是具体的实现代码:

    [cpp] view plain copy
    1. unsigned char shift_fun2(unsigned char data)  
    2. {  
    3.     data=(data<<4)|(data>>4);  
    4.     data=((data<<2)&0xcc)|((data>>2)&0x33);  
    5.     data=((data<<1)&0xaa)|((data>>1)&0x55);  
    6.     printf("  after shift fun2 data=%x  ",data);  
    7.   
    8.     return data;  
    9. }  

    总结

    交换字节的高低位并不是一个很常见的问题,遇到该问题时,需要经过仔细的分析,加上对C语言位操作的熟练掌握,就能够很好的解决这一类的问题。

  • 相关阅读:
    leetcode 之Binary Tree Postorder Traversal
    关于java中this的一些总结
    Javascript的匿名函数与自执行
    js 闭包学习笔记
    滚动条到底自动加载数据
    AMD:异步模块定义
    Sass、LESS 和 Stylus
    【原创】Mysql设置自增长主键的初始值
    -webkit-animation的使用
    CSS滤镜
  • 原文地址:https://www.cnblogs.com/alan666/p/8312003.html
Copyright © 2011-2022 走看看