问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由09、大写字母AF组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
【提示】
先将十六进制数转换成某进制数,再由某进制数转换成八进制。
#include <iostream>
#include <map>
#include <string>
#include <math.h>
using namespace std;
map<char, string> m1;
map<int, string> m2;
// 用来十六进制转二进制
void init1()
{
m1['0'] = "0000";
m1['1'] = "0001";
m1['2'] = "0010";
m1['3'] = "0011";
m1['4'] = "0100";
m1['5'] = "0101";
m1['6'] = "0110";
m1['7'] = "0111";
m1['8'] = "1000";
m1['9'] = "1001";
m1['A'] = "1010";
m1['B'] = "1011";
m1['C'] = "1100";
m1['D'] = "1101";
m1['E'] = "1110";
m1['F'] = "1111";
}
// 用来二进制转八进制
void init2()
{
m2[0] = "0";
m2[1] = "1";
m2[2] = "2";
m2[3] = "3";
m2[4] = "4";
m2[5] = "5";
m2[6] = "6";
m2[7] = "7";
m2[8] = "0";
}
int main(int argc, char *argv[]) {
using namespace std;
init1();
init2();
// n:要转换的十六进制字符串的个数
int n;
scanf_s("%d", &n);
// 没有使用一个字符串来循环赋值,
// 原因是在终端中输入一次输入多行会只赋值最后一行,
// 只进行一次转换
string* thy1 = new string[n];
for (int i = 0; i < n; i++)
{
cin >> thy1[i];
}
for (int i = 0; i < n; i++)
{
string thy2;
// 十六进制转二进制
for (int j = 0; j < thy1[i].length(); j++)
thy2 += m1[thy1[i][j]];
string thy3;
int flag = 1;
int sum = 0;
// 二进制转八进制
for (int i = 0; i < thy2.length(); i++)
{
if (thy2[thy2.length() - i - 1] == '1')
switch (flag)
{
case 1: sum += 1; break;
case 2: sum += 2; break;
case 3: sum += 4; break;
default:break;
}
if (flag == 3)
{
thy3 += m2[sum];
sum = 0;
flag = 0;
}
flag++;
}
// 判断十六进制剩余位数是否需要转换
if (flag != 1)
thy3 += m2[sum];
// 去除头部的0
int temp5 = 0;
for(int i = 0; i < thy3.length(); i++)
{
if (thy3[thy3.length() - i - 1] == '0')
temp5++;
else
break;
}
// 逆序输出
for (int i = 0; i < thy3.length()-temp5; i++)
{
cout << thy3[thy3.length() - i - 1 - temp5];
}
cout << endl;
}
}