问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。 接下来n行,每行一个由0
~9,大写字母A-F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
题目分析:
注意到输入数据巨大(100000),不能直接使用系统类型进行存储转换。我们考虑先将16进制转2进制,然后将2进制转8进制。
16进制转2进制是每个数字或字母对应4个2进制位,2进制转8进制是3个进制位转1一个进制位。
代码及注释:
#include <bits/stdc++.h>
using namespace std;
char c[11][100040];//存输入
string b[11];//由于单个string近乎可以无限存储,所以可以采用string数组存储数据
string g[17] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000",
"1001", "1010", "1011", "1100", "1101", "1110", "1111"
};//此数组作为字典用来查询16进制对应的二进制数字
int main() {
int n;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> c[i];
}
for (int i = 0; i < n; i++) {
for (int j = 0; c[i][j] != '\0'; ++j) {
if (c[i][j] >= '0' && c[i][j] <= '9') {
b[i] += g[c[i][j] - '0'];//如果是数字就填入二进制数字
} else {
b[i] += g[c[i][j] - 'A' + 10];//字母
}
}
}
string::iterator it; //指向string类的迭代器。你可以理解为指针
for (int i = 0; i < n; i++) {
for (it = b[i].begin(); *it != '1';) {
if (*it == '0') {
b[i].erase(it); //去除前面的0,注意erase之后it会自动指向下一位所以不用it++
}
}
//cout << b[i] << endl;
}
for (int i = 0; i < n; i++) {
int len = b[i].length();
int k = len % 3;//取数字要从个位三个三个取,最大位不一定能取三个
int t = 0;
int p = 0;
for (int j = 0; j < len;) {
//处理一行数 3个一位
if (j == 0&&k!=0) {//如果最大位不能取三个
for (p = 0; p < k; p++) {
t = 2 * t + b[i][p]-'0';//取k位
}
cout << t;//取了就输出
j += k;//后移k位
continue;
}
for (p = j, t = 0; p < j + 3; p++) {
t = 2 * t + b[i][p]-'0';
}
cout << t;
j += 3;
}
cout << endl;
}
}