题解
二进制转八进制
1 条题解
-
0
解题思路
这道题和"二进制转十六进制"思路一样,只是分组大小不同:1位八进制数,正好用3位二进制数表示。 因为3位二进制数最小是
000(0),最大是111(7),正好对应八进制的一位 0~7。和十六进制题不同的地方:二进制长度不一定是 3 的倍数,所以先要在最左边补 0,把长度补成 3 的倍数。 比如样例
111100001111000011110000长度是 24,正好是 3 的倍数;如果长度不是 3 的倍数,就前面补 0。具体做法:
- 读入二进制字符串 s。
- 用 while 循环在开头补 0,直到长度是 3 的倍数:
s = "0" + s。 - 每 3 位一组,把这一组二进制数转成十进制数值 v(范围一定是 0~7),直接输出这个数字就是八进制的一位。
- 去掉前导0:最前面一组如果是
000,不要输出;如果全是 0 就输出一个0。
用样例验证:
111100001111000011110000从右往左每 3 位分一组:111100001111000011110000,分别对应 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