问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
【提示】
先将十六进制数转换成某进制数,再由某进制数转换成八进制。
题意:给定一个十六进制的数,转化为8进制的输出
思路:主要是怕溢出,所以考虑使用string来完成,先把十六进制的数对应的数转化为二进制的,然后把二进制的转化为八进制,十六进制转化为二进制是一个数用4位二进制的数表示,而八进制的数转化位二进制是一个数用3位二进制的数表示。根据这个特点,先把十六进制的数对应的二进制的数进行拼接,然后对不够3倍数进行前面填0,最后对该二进制字符串进行每三位的遍历,转化为八进制的。
代码:
#include <iostream>
#include<string>
#include<ctype.h>
using namespace std;
string a[16]={"0000","0001","0010","0011","0100","0101","0110","0111","1000","1001"
,"1010","1011","1100","1101","1110","1111"};//保存十六进制每个数对应的二进制
string b[8]={"000","001","010","011","100","101","110","111"};//保存八进制每个数对应的二进制
char caleight(string s){
for(int i=0;i<8;i++){
if(s==b[i]){
return i+'0';
}
}
}
int main(int argc, char *argv[]) {
int n,cnt = 0,p;
string str;
cin>>n;
for(int j = 0;j<n;j++){
cin>>str;
string ans,num;
for(int i=0;i<str.length();i++){//把16进制对应的二进制求出来
num+=isdigit(str[i])?a[(str[i]-'0')]:a[(str[i]-'A')+10];//把对应的二进制连接起来
}
p = num.length();
while(p%3!=0)p++;
num.insert(0,p-num.length(),'0');//补齐前面的不够的0
for(int i = 0;i<num.length();i+=3){
ans+=caleight(num.substr(i,3));
}
while(ans[0]=='0'){
ans.erase(ans.begin());//去掉前面的0
}
cout<<ans<<endl;
}
return 0;
}