问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
注意
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
39
123ABC
样例输出
71
4435274
4435274
提示
先将十六进制数转换成某进制数,再由某进制数转换成八进制。
一般的思路是将十六进制转换为十进制,然后转换为八进制.
一段示例代码:
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
long long hex_to_dec(string hex)
{
long long dec = 0;
int len = hex.length();
for(int i=0 ;i<len;i++)
{
if(hex[i] >= \'A\')
{
dec += (hex[i] - \'A\' + 10)*pow(16,len-1-i);
}
else
{
dec += (hex[i] - \'0\')*pow(16,len-1-i);
}
}
return dec;
}
void dec_to_oct(long long dec)
{
char a[100];
long long s = dec;
int i = 0;
while(s/8 != 0)
{
a[i++] = \'0\' + s%8;
s = s/8;
}
a[i] = \'0\' + s;
while(i>=0)
{
cout<<a[i--];
}
}
int main()
{
string str[10];
int n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>str[i];
}
for(int i=0;i<n;i++)
{
dec_to_oct(hex_to_dec(str[i]));
cout<<endl;
}
return 0;
}
如果提交上面的代码系统会判定代码错误,因为题目中有一句话:每个十六进制数长度不超过100000。这句话说明该十六进制数有可能是一个长度为100000的数,这不是long long 类型变量所能表示的,这应该就是错误所在。
做大数运算的常用手段就是字符串变量,这里我们使用字符串变量来表示对应的二进制数,得到下面的解法:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string hex[10];
string bin[10];
string oct[10];
int n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>hex[i];
}
//16进制转2进制
for(int i=0;i<n;i++)
{
for(int j=0;j<hex[i].length();j++)
{
switch(hex[i][j])
{
case \'0\':bin[i] += "0000";break;
case \'1\':bin[i] += "0001";break;
case \'2\':bin[i] += "0010";break;
case \'3\':bin[i] += "0011";break;
case \'4\':bin[i] += "0100";break;
case \'5\':bin[i] += "0101";break;
case \'6\':bin[i] += "0110";break;
case \'7\':bin[i] += "0111";break;
case \'8\':bin[i] += "1000";break;
case \'9\':bin[i] += "1001";break;
case \'A\':bin[i] += "1010";break;
case \'B\':bin[i] += "1011";break;
case \'C\':bin[i] += "1100";break;
case \'D\':bin[i] += "1101";break;
case \'E\':bin[i] += "1110";break;
case \'F\':bin[i] += "1111";break;
default :break;
}
}
}
//2进制转8进制
for(int i=0;i<n;i++)
{
int len = bin[i].length();
int num = 0;
int temp = 3;
for(int j=len-1;j>=0;j--)
{
if(bin[i][j] == \'1\')
{
switch(temp)
{
case 3: num +=1;break;
case 2: num +=2;break;
case 1: num +=4;break;
default:break;
}
}
temp--;
if(temp == 0)
{
oct[i] += num + \'0\';
num = 0;
temp = 3;
}
}
if(temp != 0)
{
oct[i] += num + \'0\';
}
}
//对8进制数逆序
for(int i=0;i<n;i++)
{
char temp;
int len = oct[i].length();
for(int j=0;j<len/2;j++)
{
temp = oct[i][j];
oct[i][j] = oct[i][len-1-j];
oct[i][len-1-j] = temp;
}
}
//输出数据
for(int i=0;i<n;i++)
{
int len = oct[i].length();
int j=0;
while(oct[i][j++] == \'0\');
for(--j;j<len;j++)
{
cout<<oct[i][j];
}
cout<<endl;
}
return 0;
}