题解
二进制转十六进制
1 条题解
-
0
解题思路
这道题要把二进制整数转换成十六进制整数。
先记住一个非常重要的对应关系:1位十六进制数,正好用4位二进制数表示。 因为4位二进制数最小是
0000(0),最大是1111(15),而十六进制的一位正好表示 0~15,所以0000~1111正好对应十六进制的0~9、A~F。具体做法:
- 读入二进制字符串 s。
- 从最左边开始,每 4 位分成一组(题目保证长度是 4 的倍数,不用补位)。
- 把每组 4 位二进制数转换成十进制数值 v:从高位到低位,每读一位就
v = v * 2 + (这一位是0还是1)。比如0110:先 v=0,读到0得0,读到1得1,读到1得3,读到0得6。 - 查表法输出:建一个字符串
"0123456789ABCDEF",v 是几就输出第几个字符。比如 v=10 就输出A。 - 去掉前导0:如果最前面一组是
0000,转换后开头就是0,按照"整数"的习惯应该去掉。如果整个二进制数全是0,就输出一个0。
用样例验证:
011010100101分成011010100101三组:0110→ 0×2+0=0,0×2+1=1,1×2+1=3,3×2+0=6 → 输出61010→ 1,2,5,10 → 输出A0101→ 0,1,2,5 → 输出5
结果就是
6A5,和样例完全一致。参考代码
#include <iostream> using namespace std; // 用途:把二进制整数(长度是4的倍数,100位以内)转换成十六进制整数 int main() { string s; cin >> s; // 读入二进制字符串 string h = "0123456789ABCDEF"; // 0~15 对应的十六进制字符表 bool started = false; // 是否已经开始输出(用来去掉前导0) // 每4位二进制数正好对应1位十六进制数,直接分组转换 for (int i = 0; i < s.size(); i += 4) { int v = 0; // v 存放这一组4位二进制数的值 for (int j = 0; j < 4; j++) // 逐位累加,把二进制数转成十进制值 v = v * 2 + (s[i + j] - '0'); if (!started && v == 0) continue; // 前导的0组不输出 started = true; cout << h[v]; // 查表输出对应的十六进制字符 } if (!started) cout << '0'; // 二进制数全是0时输出一个0 cout << endl; return 0; }复杂度分析
- 时间复杂度:二进制数最多 100 位,每个字符只被处理一次,所以是 O(n),其中 n 是二进制数的位数。
- 空间复杂度:只用了一个字符串存输入,是 O(n)。
100 位对计算机来说非常小,瞬间就能算完。
- 1