字符串的逆反序输出算法整理


五一放假了,小伙伴们都去玩耍了,每个小伙伴均被分配一个编号,编号格式为一组16进制表示的数字串,如123456789abc,表示由0x12/0x34/0x56/0x78/0x9a/0xbc组成的6个数字串。
伙伴编号是通过一种称为逆反序输出的算法求得,算法原理是对于一串输入,先按bit逆向反转,再对每个bit取反输出。
逆向反转的意思是将输入的第1位移到最后1位,第2位移到倒数第2位,依次类推。
如对于16进制表示的输入数据:123456789abc,按二进制表示为:
000100100011010001010110011110001001101010111100,先按bit反转,得到:
001111010101100100011110011010100010110001001000,再按bit取反,得到:
110000101010011011100001100101011101001110110111,最后,换算成16进制格式表示输出:
c2a6e195d3b7
注:一个字节的16进制格式表示总是由2个字符组成,即使高4位为0,且字母部分使用小写表示。转换完的数字串长度总是与转换前的一致。
要求设计这样一个算法:
输入
第一行为一个数字,表示用例数N,从第二行开始,每行表示一个测试用例,内含使用16进制格式表示的输入数据(最大长度为100字节)。
输出
输出N行,每一行对应一个用例的逆反序运算结果,使用16进制格式表示。

题目拆分:

输入模块

键盘输入一组字符:0 ~ 9, a ~ f,来表示。
例: 键入“123456789abc”,共12个字节,
表示0x12/0x34/0x56/0x78/0x9a/0xbc,6个数字

操作要求

逆反序输出算法
算法原理是对于一串输入,先按bit逆向反转,再对每个bit取反输出。

例:
12/ 34/ 56/ 78/ 9a/ bc
16进制表示:
0x12/ 0x34/ 0x56/ 0x78/ 0x9a/ 0xbc
2进制表示:
00010010/ 00110100/ 01010110/ 01111000/ 10011010/ 10111100
按bit逆序:
00111101/ 01011001/ 00011110/ 01101010/ 00101100/ 01001000
按bit取反:
11000010/ 10100110/ 11100001/ 10010101/ 11010011/ 10110111
16进制表示:
c2/ a6/ e1/ 95/ d3/ b7

一个字节的16进制格式表示总是由2个字符组成,即使高4位为0,且字母部分使用小写表示。转换完的数字串长度总是与转换前的一致。

求解思路

首先考虑用什么方式来接收输入信息”123456789abc”。按题意应该是要按12,34,56,78,9a,bc这样接收,但一时想不出之后要如何处理。
于是就想按1,2,……,b,c这样先逐个字符的接收处理,并为了防止移位时符号位的干扰,存储变量皆定义为无符号字符类型。

按1,2,……,b,c接收到的字符以16进制显示如0x01, 0x02, ……, 0x0b, 0x0c。此处对 ’0’ ~ ’9’ 进行了减 ’0’ 操作,对 ‘a’ ~ ’f’ 进行了减 ’a’ 加 10 的操作。

因为对整体按bit进行逆序排列 等价于 对各字节按bit进行逆序排列后再对各字节按字节进行逆序排列。

此处上网查阅到了一种跟巧妙地按bit逆序的方法:
链接:https://blog.csdn.net/jakee304/article/details/2152655.

#define exchange(x,y) /
		{
    (x) ^= (y);  /
		  (y) ^= (x);  /
		  (x) ^= (y);  /
		}

unsigned char fun1(unsigned char c)
{
   
        union {
   
                unsigned char c;
                struct {
   
                        unsigned char bit0:1;
                        unsigned char bit1:1;
                        unsigned char bit2:1;
                        unsigned char bit3:1;
                        unsigned char bit4:1;
                        unsigned char bit5:1;
                        unsigned char bit6:1;
                        unsigned char bit7:1;
                } bchar;
        } ubc;
        ubc.c = c;
        exchange(ubc.bchar.bit0, ubc.bchar.bit7);
        exchange(ubc.bchar.bit1, ubc.bchar.bit6);
        exchange(ubc.bchar.bit2, ubc.bchar.bit5);
        exchange(ubc.bchar.bit3, ubc.bchar.bit4);

        return ubc
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值