问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
【提示】
先将十六进制数转换成某进制数,再由某进制数转换成八进制。
我的想法:
复习的时候发现这种简单题竟然不会!?相当受打击了,一开始的想法是将输入的十六进制数强转为十进制,再按照公式转为八进制,可题目给的数据挺大的,肯定会超时,网上搜了答案都是转为二进制再转八进制,按照自己思路整理了一下,方便复习。
代码如下:
#include<iostream>
#include<cstring>
using namespace std;
void trans(string s)
{
int len1=s.size();
string res1="";
for(int i=0;i<len1;i++)//十六进制转八进制
{
switch(s[i]){
case '0': res1 += "0000";break;
case '1': res1 += "0001"; break;
case '2': res1 += "0010"; break;
case '3': res1 += "0011"; break;
case '4': res1 += "0100"; break;
case '5': res1 += "0101"; break;
case '6': res1 += "0110"; break;
case '7': res1 += "0111"; break;
case '8': res1 += "1000"; break;
case '9': res1 += "1001"; break;
case 'A': res1 += "1010"; break;
case 'B': res1 += "1011"; break;
case 'C': res1 += "1100"; break;
case 'D': res1 += "1101"; break;
case 'E': res1 += "1110"; break;
case 'F': res1 += "1111"; break;
}
}
if(res1.size()%3==1) res1="00"+res1;
if(res1.size()%3==2) res1="0"+res1;
string res2="";
int len2=res1.size();
for(int i=0;i<len2;i+=3)
{
string t=res1.substr(i,3);
if(i==0&&t=="000") res2 +="";//避免因为000导致转换为八进制时有前导0
else res2 +=((4*(t[0]-'0')+2*(t[1]-'0')+(t[2]-'0')))+'0';
}
cout<<res2<<endl;
}
int main()
{
//进制转换
int n;
cin>>n;
string dates[n];//存储输入string字符串
for(int i=0;i<n;i++)
{
cin>>dates[i];
}
for(int i=0;i<n;i++)//遍历每一个字符串进行转换
{
trans(dates[i]);
}
return 0;
}