问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由0-9、大写字母A-F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
【提示】
先将十六进制数转换成某进制数,再由某进制数转换成八进制。
思路: 起初在做的时候先用的是常规的方式,写进制转换的函数将十六进制转换为十进制,再将十进制转换为八进制。后来发现题目中给的范围太大了,100000长度的十六进制用整型无法存储计算。后来用二进制作转换的媒介的方式才算是做出了这道题。
例如进制转换表:
十六进制 | 二进制 | 八进制 |
---|---|---|
0 | 0000 | 000 |
1 | 0001 | 001 |
2 | 0010 | 010 |
3 | 0011 | 011 |
4 | 0100 | 100 |
5 | 0101 | 101 |
6 | 0110 | 110 |
7 | 0111 | 111 |
8 | 1000 | – |
9 | 1001 | – |
10 | 1010 | – |
11 | 1011 | – |
12 | 1100 | – |
13 | 1101 | – |
14 | 1110 | – |
15 | 1111 | – |
#include <iostream>
#include <string>
using namespace std;
int main()
{
int i,j,n;
string a="";
string b[16]={
"0000","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111"};
string c[9]={
"000","001","010","011","100","101","110","111"};
string d="";
string e="";
string str;
cin>>n;
while(n--)
{
cin>>a;
for(i=0;i<=a.size()-1;i++)
{
if(a[i]>='0'&&a[i]<='9')
{
d+=b[a[i]-'0'];
}
else {
d+=b[a[i]-'A'+10];
}
}
for(i=d.size()-1;i>=0;i=i-3)
{
str="";
if(i==0)
{
str+='0';
str+='0';
str+=d[i];
}
else if(i-1==0)
{
str+='0';
str+=d[i-1];
str+=d[i];
}
else {
str+=d[i-2];
str+=d[i-1];
str+=d[i];
}
for(j=0;j<8;j++)
{
if(str==c[j])
{
e+=(j+'0');
break;
}
}
}
for(i=e.size()-1;i>=0;i--)
{
if(i==e.size()-1&&e[i]=='0')
{
continue;
}
cout<<e[i];
}
cout<<endl;
a="";
d="";
e="";
}
return 0;
}
样例输入:
B441E2411DC709E111C7E1E7ACB6F8CAC0BB2FC4C8BC2AE3BAAAB9165CC458E199CB89F51B135F7091A5ABB0874DF3E8CB45
样例输出:
13210170440435616047410434374171726266761453005662770462136052707352525621313461054341463456117521542327670221513256604164676372145505