蓝桥杯基础练习 十六进制转八进制

蓝桥杯基础练习 十六进制转八进制

资源限制
时间限制: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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值