//刷题笔记
题目:
问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由0~ 9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
【提示】
先将十六进制数转换成某进制数,再由某进制数转换成八进制。
解题思路如下:
以字符格式输入十六进制将其转换为十进制再转换为二进制最后再转换为八进制。
在将十六进制转换为int 数字时,对于0~9范围内我们可以用’0’-‘0’,(相当于减去0字符的ASCII值48,从而得到本身的int 数值)
// 化数字为int型
if(ch>='0'&&ch<='9')
return ch-'0';
//化A~F直接返回
case 'A':
return 10;
代码如下:代码片
。
#include<stdio.h>
#include<string.h>
#define Max_N 10
#define Max_L 100000
#define Max_D 400000
int Bin[Max_D];//存放二进制
int Oct[Max_D];//存放八进制
//十进制转换二进制
void Dec_Bin(int m,int n) {//传进的n为第i个int十六进制,比如4F十六进制,4是第0个,存放4的二进制是从b[3]开始依次递减,因为辗转相除的余数倒过来才是正的二进制
int i;
for(i=3; i>=0; i--) {
Bin[n*4+i]=m%2;//辗转相除法
m /=2;
}
}
//十六进制转换十进制
int Hex_Dec(char ch) {
if(ch>='0'&&ch<='9')
return ch-'0';
switch(ch) {
case 'A':
return 10;
case 'B':
return 11;
case 'C':
return 12;
case 'D':
return 13;
case 'E':
return 14;
case 'F':
return 15;
}
return -1;
}
//打印八进制结果
void print(int Oct[],int n) {
int i;
for(i=n-1;i>=0;i--){
printf("%d",Oct[i]);
}
printf("\n");
}
//二进制转换八进制
int Bin_Oct(int L) {
int i,j=0;
for(i=L*4-3; i>=0; i-=3) {//从倒数第三个开始依稀三个递减转换为八进制
if(i==0&&!(Bin[i]*4+Bin[i+1]*2+Bin[i+2]))
break;
Oct[j++]=Bin[i]*4+Bin[i+1]*2+Bin[i+2];
}
if(i==-2){
if(Bin[0]){
Oct[j++]=Bin[0];
}
}
else if(i == -1){
if(Bin[0]*2+Bin[1])
Oct[j++]=Bin[0]*2+Bin[1];
}
return j;
}
//十六进制转八进制
void Hex_Oct(char s[]) {
int i,n;
for(i=0; i<(int)strlen(s); i++) {
Dec_Bin(Hex_Dec(s[i]),i);//十六进制转十进制再转二进制
}
n=Bin_Oct(strlen(s));
print(Oct,n);
}
int main() {
int i,n;
char s[Max_N][Max_L];//存放n个十六进制数的二维数组
scanf("%d",&n);
for(i=0; i<n; i++) {
scanf("%s",&s[i]);
}
for(i=0; i<n; i++) {
Hex_Oct(s[i]);
}
return 0;
}