top1编程
← 返回题目
题解

二进制转十六进制

1 条题解

  • 0
    @ 2026-8-5 12:17:22

    解题思路

    这道题要把二进制整数转换成十六进制整数。

    先记住一个非常重要的对应关系:1位十六进制数,正好用4位二进制数表示。 因为4位二进制数最小是 0000(0),最大是 1111(15),而十六进制的一位正好表示 0~15,所以 0000~1111 正好对应十六进制的 0~9、A~F。

    具体做法:

    1. 读入二进制字符串 s。
    2. 从最左边开始,每 4 位分成一组(题目保证长度是 4 的倍数,不用补位)。
    3. 把每组 4 位二进制数转换成十进制数值 v:从高位到低位,每读一位就 v = v * 2 + (这一位是0还是1)。比如 0110:先 v=0,读到0得0,读到1得1,读到1得3,读到0得6。
    4. 查表法输出:建一个字符串 "0123456789ABCDEF",v 是几就输出第几个字符。比如 v=10 就输出 A。
    5. 去掉前导0:如果最前面一组是 0000,转换后开头就是0,按照"整数"的习惯应该去掉。如果整个二进制数全是0,就输出一个 0。

    用样例验证:011010100101 分成 0110 1010 0101 三组:

    • 0110 → 0×2+0=0,0×2+1=1,1×2+1=3,3×2+0=6 → 输出 6
    • 1010 → 1,2,5,10 → 输出 A
    • 0101 → 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