一、[题目] 进制转换4 (十六进制转八进制)
时间限制:1.0s 内存限制:512.0MB
问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
注:十六进制数中的10~15分别用大写的英文字母A、B、C、D、E、F表示。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
注意
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
提示
先将十六进制数转换成某进制数,再由某进制数转换成八进制。
二、[代码]:
PS. 进制转换4 (十六进制转八进制) 是也是上一道题 进制转换3(十六进制转十进制) 的变形,要注意的是题目给出的提示,我们可以利用中间进制进行转换,以下列出我的解法。
算法一: 基本库函数法(利用C库函数strupr(), strlen(), isdigit(), pow() , itoa() 以及 printf() 的格式化输出)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
int main()
{
char T[100000];
int i;
scanf("%d",&i);
while(i--){
scanf("%s",T); strupr(T);
int P=strlen(T),L=P;
double N=0,X=16;
while(P--){
N+=isdigit(T[P])?(T[P]-'0')*pow(X,L-P-1):(T[P]-'A'+10)*pow(X,L-P-1);
}
printf("%s\n",itoa(N,T,8)); //或者 printf("%o\n",int(N));
}
return 0;
}
PS. 其实该算法这么写是错误的,由题目我们知道十六进制的位数有可能达到100000位,而该算法只对不大的十六进制转化有效,这麽一来该算法就吃不消了。
算法二:高精度算法(利用二进制作为中间转换数---每3位二进制数对应一个八进制数,每4位二进制数对应一个十六进制数)
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
char T[100000];
char W[400000]; //存取二进制的大数组,为了节省内存开销,我们也可以根据实际使用大小动态申请该数组
int i;
scanf("%d",&i);
while(i--){
scanf("%s",T); strupr(T);
int A=0,L=0,P=strlen(T);
memset(W,0,sizeof(W));
while(P--){ //将十六进制转换成二进制
A=isdigit(T[P])?(T[P]-'0'):(T[P]-'A'+10);
while(A>0){ //利用模2求余法将十进制转换成二进制
W[L++]=A%2;
A=(A-W[L-1])/2;
}
if(L%4>0) L=L+4-L%4; //对二进制进行4位补齐
}
if(L%3>0) L=L+3-L%3; //对二进制进行3位补齐
L--;
while(L>0){ //将二进制转换成八进制
if(L>1) A=W[L]*4+W[L-1]*2+W[L-2];
else A=W[L]*4+(L>0?W[L-1]*2:0);
if(L<L-3||A>0) printf("%o",A); //如果前导为0则不进行输出
L-=3;
}
printf("\n");
}
return 0;
}
欢迎评论和转载,转载请注明文章出处,我对此表示最真诚的敬意!