试题 基础练习 十六进制转八进制
问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由09、大写字母AF组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
【提示】
先将十六进制数转换成某进制数,再由某进制数转换成八进制。
#include<bits/stdc++.h>
using namespace std;
int n;//有几个输入案例
//十六进制与二进制的对应关系
string h[16]={"0000","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111"};
map<string,int>mp;//用来保存二进制与八进制的对应关系
string fun16(string s){//16进制转2进制的函数
string ans="";
int len=s.size();
for(int i=0;i<len;i++){
if(s[i]>='0'&&s[i]<='9'){//是数字
ans+=h[s[i]-'0'];
}else {
ans+=h[(s[i]-'A'+10)];//是字母
}
}
return ans;
}
//将2进制转换为8进制
string fun8(string s){
string ans="";
int len=s.size();
if(!(len%3==0)){
int a=3-(len%3);
while(a--) s='0'+s;//在字符串前面补零
}//保证字符串的长度是3的整数倍
for(int i=0;i<len;i+=3){
ans+=mp[s.substr(i,3)];//每3位为一组,转换为8进制
}
return ans;
}
//去除最后结果的前导零
string fun(string s){
while(s.size()&&s[0]=='0'){
s=s.substr(1);
}
return s;
}
int main(){
mp["000"]='0',mp["001"]='1',mp["010"]='2',mp["011"]='3',mp["100"]='4',mp["101"]='5',mp["110"]='6',mp["111"]='7';
cin>>n;
for(int i=0;i<n;i++){
string s;cin>>s;
string temp1=fun16(s);
string temp2=fun8(temp1);
string ans=fun(temp2);
cout<<ans<<endl;
}
}
思路
为了方便操作,统一将数字类型转换为string
型。
1.先将十六进制转为二进制,在转八进制时,用一个string
数组来存0~15和二进制的对应关系,用for循环将每一位s[i]
转换为对应的二进制字符串。注意:转换时首先要判断是数字还是字母。
2.再将二进制转换为八进制,将整个字符串每三位截取一组,在截取前,要在整个字符串的前面补零,保证字符串的长度是3的整数倍。用map来保存二进制和八进制的转换关系。
3.最后要判断答案的字符串是否有前导零,并去除。