问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由09、大写字母AF组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
思路:刚开始想得是先转换成十进制,但是字符串长度太大了。所以先转化成二进制,转化成二进制之后,如果字符串长度不是3的倍数,就在前面补0,每三位二进制数化为一个八进制数即可。
AC代码:
#include<bits/stdc++.h>
using namespace std;
int n;
string res,ans;
stack<int> s,t;
string binary[]={"0000","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010",
"1011","1100","1101","1110","1111"}; //先定义好0-16的二进制数
map<string,string> a;
void init() {
a["000"]="0"; //二八转换
a["001"]="1";
a["010"]="2";
a["011"]="3";
a["100"]="4";
a["101"]="5";
a["110"]="6";
a["111"]="7";
}
void converse(string str) {
res="";
ans="";
int cur;
for(int i=0;i<str.length();i++) {
if(str[i]>='0'&&str[i]<='9') {
cur=(int)(str[i]-48);
}else {
cur=(int)(str[i]-55);
}
res+=binary[cur]; //转成二进制
}
int n=res.length();
int x=n%3;
if(x==1) {
res="00"+res; //补0
}else if(x==2) {
res="0"+res;
}
for(int i=0;i<res.length();i+=3) {
ans+=a[res.substr(i,3)]; //每三位转成一位八进制数
}
int i=0;
for(i=0;i<ans.length();i++) {
if(ans[i]!='0') { //注意不能输出前导0
break;
}
}
ans.erase(0,i);
cout<<ans<<endl;
}
int main() {
init();
int n;
cin>>n;
string str;
for(int i=1;i<=n;i++) {
cin>>str;
converse(str);
}
return 0;
}