[算法题]半字节交换

题目:将十六进制数12345678 转换为87654321并输出

通过两种方法进行解答

1.指针交换法

2.蝶式交换法

 

 

指针交换法:

#include <stdio.h>
#include <iostream>
using namespace std;
int main(){
    int x = 0x12345678; //初始化十六进制数12345678
    int a[10];          //用于保存交换相关的数据
    char *p_char;       //获取数据的指针
    char *pex_char;     //输出数据的指针
    p_char = (char *)&x;   //获取一字节数据 进行半字节交换
    pex_char = (char *)&x;

    //半字节交换
    for (int i = 0; i < 4; i++){
        a[i] = *p_char;    //获取1字节数据,如0x78

        a[i] = ((a[i] & 0x0f) << 4) | (a[i] >> 4);
        //1.取后四位 左移四位
        //  0x78 = 01111000, 0x78 & 0x0f --> 01111000 & 00001111 = 00001000
        //  左移四位-->10000000(右边自动补0)
        //2.因为左边四位为0000,所以右边直接右移四位
        //  0x78 = 01111000, 右移四位 --> 00000111
        //3.左右两边进行按位或运算 10000000 | 00000111 = 10000111 -->0x87

        p_char++;         //获取下1字节数据
                           //通过循环将 12345678 -> 21 43 65 87  
        
    }
    //循环结束后  a[0]=0x21  a[1]=0x43 a[2]=0x65 a[3]=0x87
    //将21 43 65 87 逆序输出 即 87 65 43 21,循环从高位开始。
    for (int i = 3; i >= 0; i--){
        *pex_char = a[i];  //通过指针修改x的值
        *pex_char++;       //指向下一位
    }
    printf("x = %#x\n", x);//按十六进制输出
    return 0;
}

 

 

蝶式交换法

#include <iostream>
#include <stdio.h>
using namespace std;
int main() {
    //设原始位为 1234  5678
    int data = 0x12345678;
    data = (data << 16) | (data >> 16);
    //data<<16,数据左移16位,5678 0000;data>>16,数据右移16位,0000 1234;|按位或  ,之后位序为 5678   1234
    data = ((data << 8) & 0xff00ff00) | ((data >> 8) & 0x00ff00ff);
    //5678 1234  data<<8左移8位,7812 3400;&按位与ff00 ff00,得7800 3400;data>>8,
    // 右移8位,0056 7812,位与00ff 00ff,得0056 0012;位或之后位序为 7856   3412
    data = ((data << 4) & 0xf0f0f0f0) | ((data >> 4) & 0x0f0f0f0f);
    //7856 3412左移4位8563 4120,位与f0f0 f0f0得8060 4020;右移4位 0785 6341,
    // 位与0f0f 0f0f得0705 0301,;位或之后位序为 8765    4321
    printf("data = %#x\n", data);
    return 0;
}

 

小结:两种算法的核心都是半字节交换,其核心是相关的位操作(按位与、或,位移等等)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值