蓝桥杯基础练习 十六进制转八进制
资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由09、大写字母AF组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
【提示】
先将十六进制数转换成某进制数,再由某进制数转换成八进制。
(这个不是我自己敲的,写的时候有这个想法,和一个学弟说了,那个学弟完成的)
#include<stdio.h>
#include<string.h>
int main(){
int i,j,k,n,t,q;
char c[10][200001];
char a[100001],b[400001];
scanf("%d",&n);//至多10个
getchar();//吸收\n
for(i=0;i<n;i++){
k=4;//为后面补位做铺垫,先预留出来用来补零的
gets(a);//取数(输入)
q=0;//输出的数组
for(j=0;a[j]!='\0';j++,k+=4){//转换为2进制数 ,注意此时k从4开始循环,预留出来四位补零
switch(a[j]){
case '0':strcpy(&b[k],"0000");break;
case '1':strcpy(&b[k],"0001");break;
case '2':strcpy(&b[k],"0010");break;
case '3':strcpy(&b[k],"0011");break;
case '4':strcpy(&b[k],"0100");break;
case '5':strcpy(&b[k],"0101");break;
case '6':strcpy(&b[k],"0110");break;
case '7':strcpy(&b[k],"0111");break;
case '8':strcpy(&b[k],"1000");break;
case '9':strcpy(&b[k],"1001");break;
case 'A':strcpy(&b[k],"1010");break;
case 'B':strcpy(&b[k],"1011");break;
case 'C':strcpy(&b[k],"1100");break;
case 'D':strcpy(&b[k],"1101");break;
case 'E':strcpy(&b[k],"1110");break;
case 'F':strcpy(&b[k],"1111");break;
default:break;
}
}
if(j*4%3==1){//多出1位,所以补两个零,记录起始下标
b[3]='0';
b[2]='0';
j=2;//补位,使二进数能被3整除
}
else if(j*4%3==2) {//多出2位,所以补一个零,记录起始下标
b[3]='0';
j=3;
}
else j=4;//整除,记录起始下标
for(;j<k;j+=3){
t=(b[j]-'0')*4+(b[j+1]-'0')*2+(b[j+2]-'0')*1;
if(t==0&&j==2||t==0&&j==3||t==0&&j==4);//第一位是0的话不用输出
else {
c[i][q]=t+'0';
q++;
}
}
}//至此大循环输入、处理结束
for(i=0;i<n;i++) {
puts(c[i]);
}
return 0;
}
第二种比较麻烦的方法是自己写的
这里其实不用指针更节约cpu,但是没有完全改过来,读者自己改一下
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
int main(){
int i,t,p,k,s=0;
int t1,j;//原本是3,前两个位置用来补0
int n,m,tap1,tap2=2;//n组16进制数,大循环
//char *a;//存放16进制数
//a = (char *)malloc(sizeof(char)*100001);
//char **p = (char *)malloc(m*sizeof(char *));
char **a;
int *b;//存放转换后的2进制数
int *temp;
temp = (int *)malloc(sizeof(int)*100001);
b = (int *)malloc(sizeof(int)*400001);
int *c;//存放8进制数
c = (int *)malloc(sizeof(int)*400001);
scanf("%d",&n);//输入n
//char **a = (char *)malloc(n*sizeof(char *));
a = (char **)malloc(n* sizeof(char *));
for(k=0;k<n;k++)
{
*(a + k) = (char *)malloc(100001 * sizeof(char));
scanf("%s",a[k]);}//输入一组十六进制数
for(k=0;k<n;k++)//大循环
{
for(m=0;a[k][m];m++)//最终m为十六进制数数组的长度
{
if(a[k][m]>='A'&&a[k][m]<='F')//如果十六进制数是A-F
*(temp+m)=a[k][m]-'A'+10;//转化为十六进制数放在*(temp+m)
if(a[k][m]>='0'&&a[k][m]<='9')//同理
*(temp+m)=a[k][m]-'0';
}
//此时a中的一组16进制数已经每一位分别转化为10进制了
/*for(i=0;i<m;i++)
printf("%d",*(temp+i));*/
//检测
j=5;
for(i=0;i<m;i++){
tap1=j-4;//tap用于记录每一组16进制的2进制数的(左边)第1个位置 (第一次temp=0)
while(j!=tap1)//如果j回到了第一个位置循环终止
{
*(b+j)=*(temp+i)%2;//将转化为10进制以后的一位16进制数求余,放在转化为二进制数的第四位
*(temp+i)=*(temp+i)/2;//求余以后转换后的16进制数除2
j--;//二进制数游标前移
}
j=j+8;//游标后移,此时j移动到下一个十六进制数的(右边第一位)
}
/*
for(i=0;i<4*m+2;i++)
printf("%d",*(b+i));*/
//测试
t1=0;
if((4*m)%3==0) t=2;//可以写if((4*m)%3==1) t=0; else t=3-((4*m)%3);
if((4*m)%3==1) t=0;//或者写 t=(3-((4*m)%3))%3 ;
if((4*m)%3==2) t=1;//数组0,1位存放0,如果2进制数为3的倍数就可以三位取8进制数
while(t<4*m+2)
{
tap2=2;
while(tap2>=0){//tap2初始化为2
p=*(b+t)*pow(2,tap2)+p;//p初始化为0
//printf("%d\n",p);
tap2--;
t++;
}
*(c+t1)=p;p=0;//y为8进制数的游标
t1++;
}
for(s=0;s<t1-1;s++)
{
if(*(c+s)!=0)
break;
}
for(i=s;i<t1;i++)
printf("%d",*(c+i));
t1=0;
printf("\n");
}
return 0;
}