基础练习 十六进制转八进
问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输入的十六进制数不会有前导0,比如012A。
样例输入
2
39
123ABC
样例输出
71
4435274
思路
如果直接转化为十进制数后再转化为二进制,长度肯定是超出了的。此时,可以先转化为二进制,再将二进制转化为八进制。
每个十六进制数对应四位二进制数,每三位二进制又决定一个八进制数。
可以用的设计技巧:用字典储存对应的进制转换值。
1 #include<iostream> 2 #include<string> 3 #include<map> 4 5 using namespace std; 6 7 map<char, string> get_map() 8 { // 建立十六进制与八进制的字典 9 map<char, string> mp; 10 mp['1'] = "0001"; mp['2'] = "0010"; mp['3'] = "0011"; mp['4'] = "0100"; 11 mp['5'] = "0101"; mp['6'] = "0110"; mp['7'] = "0111"; mp['8'] = "1000"; 12 mp['9'] = "1001"; mp['A'] = "1010"; mp['B'] = "1011"; mp['C'] = "1100"; 13 mp['D'] = "1101"; mp['E'] = "1110"; mp['F'] = "1111"; mp['0'] = "0000"; 14 return mp; 15 } 16 17 map<string, char> eight_mp() 18 { // 建立二进制与八进制的字典 19 map<string, char> mp; 20 mp["000"] = '0'; mp["001"] = '1'; mp["010"] = '2'; mp["011"] = '3'; 21 mp["100"] = '4'; mp["101"] = '5'; mp["110"] = '6'; mp["111"] = '7'; 22 return mp; 23 } 24 25 void solve(string s, map<char, string> mp, map<string, char> e_mp) 26 { 27 // 16进制转2进制 28 string t; 29 string::iterator ite; 30 for(ite=s.begin();ite!=s.end();ite++){ 31 t += mp[*ite]; 32 } 33 // 二进制转 8 进制 34 // 每三个二进制数为一个八进制数 35 int len = t.size(); 36 int l = 0; 37 int out_len = 0; 38 int flage = 1; 39 if(len%3 == 0){ 40 l = len/3; 41 out_len = l; 42 } 43 else{ 44 flage = 0; 45 l = len/3+1; 46 out_len = l; 47 // 将第一位补齐 48 if(len%3 == 1) t = "00" + t; 49 else t = "0" + t; 50 } 51 // go 52 int bg = 0; 53 // 去掉前导0 54 if(t.substr(bg, 3) == "000"){ 55 bg += 3; 56 } 57 58 for(int i=0;i<l;i++){ 59 cout<<e_mp[t.substr(bg, 3)]; 60 bg += 3; 61 } 62 cout<<endl; 63 } 64 65 int main() 66 { 67 map<char, string> mp; 68 map<string, char> e_mp; 69 mp = get_map(); 70 e_mp = eight_mp(); 71 72 int n; 73 cin>>n; 74 string *str = new string[n]; 75 76 for(int i=0;i!=n;i++){ 77 cin>>str[i]; 78 } 79 80 for(int i=0;i!=n;i++){ 81 solve(str[i], mp, e_mp); 82 } 83 84 delete []str; 85 86 return 0; 87 }