top1编程
← 返回题目
题解

二进制转八进制

1 条题解

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

    解题思路

    这道题和"二进制转十六进制"思路一样,只是分组大小不同:1位八进制数,正好用3位二进制数表示。 因为3位二进制数最小是 000(0),最大是 111(7),正好对应八进制的一位 0~7。

    和十六进制题不同的地方:二进制长度不一定是 3 的倍数,所以先要在最左边补 0,把长度补成 3 的倍数。 比如样例 111100001111000011110000 长度是 24,正好是 3 的倍数;如果长度不是 3 的倍数,就前面补 0。

    具体做法:

    1. 读入二进制字符串 s。
    2. 用 while 循环在开头补 0,直到长度是 3 的倍数:s = "0" + s。
    3. 每 3 位一组,把这一组二进制数转成十进制数值 v(范围一定是 0~7),直接输出这个数字就是八进制的一位。
    4. 去掉前导0:最前面一组如果是 000,不要输出;如果全是 0 就输出一个 0。

    用样例验证:111100001111000011110000 从右往左每 3 位分一组: 111 100 001 111 000 011 110 000,分别对应 7、4、1、7、0、3、6、0,连起来就是 74170360,和样例一致。

    参考代码

    #include <iostream>
    using namespace std;
    // 用途:把二进制整数(100位以内)转换成八进制整数
    int main() {
        string s;
        cin >> s;
        // 每3位二进制数对应1位八进制数,先把长度补成3的倍数(前面补0)
        while (s.size() % 3 != 0) s = "0" + s;
        bool started = false;            // 是否已经开始输出(用来去掉前导0)
        // 每3位一组转换成八进制数字
        for (int i = 0; i < s.size(); i += 3) {
            int v = 0;                    // v 存放这一组3位二进制数的值
            for (int j = 0; j < 3; j++)   // 逐位累加
                v = v * 2 + (s[i + j] - '0');
            if (!started && v == 0) continue;  // 前导的0组不输出
            started = true;
            cout << v;                    // v 的范围是 0~7,正好是八进制数字
        }
        if (!started) cout << '0';        // 全是0时输出一个0
        cout << endl;
        return 0;
    }
    

    复杂度分析

    • 时间复杂度:二进制数最多 100 位,每个字符只被处理一次,所以是 O(n),其中 n 是二进制数的位数。
    • 空间复杂度:用一个字符串存输入,是 O(n)。

    100 位对计算机来说非常小,瞬间就能算完。

    • 1