问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
【提示】
先将十六进制数转换成某进制数,再由某进制数转换成八进制。
思路分析:可以把十六进制先转成二进制,然后再转成八进制,一位十六进制可以转成四位二进制,一位八进制可以转成三位二进制,三位十六进制必然转成四位八进制,所以把十六进制分为每三位为一部分,注意八进制首位为0不用输出。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int N=100005;//定义的数组空间稍微大一些
int DtoO(char *s,int t,int f);//十六进制转十进制函数
//s指向十六进制数据的指针,t一位十六进制数 ,f十六进制数的个数
int main( )
{
int n,i,len;
char str_16[N];
scanf("%d",&n);
getchar();//接收回车
for(i=0;i<n;i++)
{
fgets(str_16,N,stdin);//输入字符串
len=strlen(str_16)-1;//统计字符串长度
str_16[len]='\0';//fgets()函数会接收回车
reverse(str_16,str_16+len);//倒转字符串
DtoO(str_16,0,0);//调用函数
}
return 0;
}
int DtoO(char *s,int t,int f)
{
if(*s=='\0')//字符串结束标志
{
if(t)//十六进制转八进制,可能多一位
printf("%d",t);
return 0;
}
int d;
if(*s>='A')//十六进制转十进制
d=*s-'A'+10;
else
d=*s-'0';
//每3位十六进制可以转成4位八进制
if(f%3==0)//以十进制方式,记录二进制数
t+=d;//第一位十六进制
else if(f%3==1)
t+=d*2; //第二位十六进制
if(f%3==2)
{
t+=d*4;//第三位十六进制
DtoO(++s,0,f+1);//调用递归函数,t每三位就初始化
if((t/8))//第四位八进制
printf("%d",t/8);
else if(*(s+1)!='\0')//如果八进制首位是0则不输出
printf("0");
}
else
{
DtoO(++s,t/8,f+1);
}
printf("%d",t%8);//十进制数转八进制
if(!f) printf("\n");//单个数末尾换行
return 0;
}