问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。 接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
注意
输入的十六进制数不会有前导0,比如012A。 输出的八进制数也不能有前导0。
样例输入
2 39 123ABC
样例输出
71 4435274 思路: 如果先把十六进制转化成十进制,当十六进制数很大时,会溢出,若用字符串保存结果,那么转八进制会极其复杂。所以要先把十六进制转化成二进制,每四位十六进制数对应一个二进制数,再把二进制转化成八进制,每三个二进制数对应一个八进制数。
#include <iostream>
#include<cstdio>
#include<algorithm>
#include <string>
using namespace std;
char s[100010];
void conversion(char s[])
{
string temp;
int t;
for (int i=0; s[i]!='\0'; i++)
{
if (s[i] <= '9' && s[i] >= '0')
t = s[i] - '0';
else
t = s[i] - 'A' + 10;
string tem;
while(t) //十六进制转二进制
{
tem += ((t & 1) + '0');
t >>= 1;
}
if(!tem.length())
tem = "0000";
while(tem.length() < 4)
tem += '0';
reverse(tem.begin(), tem.end());
temp += tem;
}
int i = 0;
int len = temp.length();
while(temp.length() % 3!=0)
{
temp = '0' + temp;
len++;
}
string cur;
while(i < len)
{
cur += temp[i];
if(cur.length() == 3)
{
int kk = 0;
for(int j = 0; j < 3; j++)
kk = kk * 2 + cur[j] - '0';
cur.clear();
if(kk == 0 && i == 2); //八进制前导零不输出
else
cout << kk;
}
i++;
}
cout << endl;
}
int main()
{
int n;
scanf("%d", &n);
while(n--)
{
scanf("%s", s);
conversion(s);
}
return 0;
}