十六进制转换为八进制

时间:2023-01-05 20:44:32

问题描述
  给定n个十六进制正整数,输出它们对应的八进制数。

输入格式
  输入的第一行为一个正整数n (1<=n<=10)。
  接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。

输出格式
  输出n行,每行为输入对应的八进制正整数。

  【注意】
  输入的十六进制数不会有前导0,比如012A。
  输出的八进制数也不能有前导0。

样例输入
  2
  39
  123ABC

样例输出
  71
  4435274

  【提示】
  先将十六进制数转换成某进制数,再由某进制数转换成八进制。

#include<iostream>
#include<math.h>
using namespace std;
int main () {
int n,size,length; //n代表测试样例数目 length代表十六进制字符串长度 size代表字符串转换为八进制的个数
int *p,*a;
string s;
cin>>n;
for(int k=0;k<n;k++)
{
cin>>s;
length=s.length(); //十六进制字符串的长度
size=ceil(length*4.0/3); //该字符串转换为八进制后,有size个字符
p=new int[length*4+4]; //p存储二进制 ,+4是因为有可能需要补0 比如1010,要转换为001010

//将十六进制转换为二进制
for(int i=length-1,j=0;i>=0;i--,j+=4)
{
switch(s[i])
{
case '0': p[j]=0;p[j+1]=0;p[j+2]=0;p[j+3]=0;break;
case '1': p[j]=1;p[j+1]=0;p[j+2]=0;p[j+3]=0;break;
case '2': p[j]=0;p[j+1]=1;p[j+2]=0;p[j+3]=0;break;
case '3': p[j]=1;p[j+1]=1;p[j+2]=0;p[j+3]=0;break;
case '4': p[j]=0;p[j+1]=0;p[j+2]=1;p[j+3]=0;break;
case '5': p[j]=1;p[j+1]=0;p[j+2]=1;p[j+3]=0;break;
case '6': p[j]=0;p[j+1]=1;p[j+2]=1;p[j+3]=0;break;
case '7': p[j]=1;p[j+1]=1;p[j+2]=1;p[j+3]=0;break;
case '8': p[j]=0;p[j+1]=0;p[j+2]=0;p[j+3]=1;break;
case '9': p[j]=1;p[j+1]=0;p[j+2]=0;p[j+3]=1;break;
case 'A': p[j]=0;p[j+1]=1;p[j+2]=0;p[j+3]=1;break;
case 'B': p[j]=1;p[j+1]=1;p[j+2]=0;p[j+3]=1;break;
case 'C': p[j]=0;p[j+1]=0;p[j+2]=1;p[j+3]=1;break;
case 'D': p[j]=1;p[j+1]=0;p[j+2]=1;p[j+3]=1;break;
case 'E': p[j]=0;p[j+1]=1;p[j+2]=1;p[j+3]=1;break;
case 'F': p[j]=1;p[j+1]=1;p[j+2]=1;p[j+3]=1;break;
}

}

a=new int[size]; //a存储八进制
p[length*4]=0;
p[length*4+1]=0;
p[length*4+2]=0;
for(int i=0,j=0;i<(4*length+3);i+=3,j++)
{
a[j]=p[i]*1+p[i+1]*2+p[i+2]*4;
}

//输出八进制
int i=size-1;

//为了不输出前导0,
while(a[i]==0&&i>=0) i--;
if(i<0) //全为0,正常输出
{
for(i=size-1;i>=0;i--)
{
cout<<a[i];
}
}else{
for(;i>=0;i--)
{
cout<<a[i];
}
}
cout<<endl;
}
return 0;
}