问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由09、大写字母AF组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
【提示】
先将十六进制数转换成某进制数,再由某进制数转换成八进制。
之前看了大佬的代码,都觉得直接定义出400000长的字符数组不现实,但是通过相关测试后,字符串数组的最大长度应该为2000000。
解题思路为先把16进制通过1拆4转为2进制,在3合1转为8进制。
#include <stdio.h>
#include <malloc.h>
#include <string.h>
struct Shiliu{
char s[1000001] ;
};
typedef struct Shiliu shiliu ;
struct Ba{
char s[1000001] ;
};
typedef struct Ba ba ;
struct Er{
char s[4000001] ;
};
typedef struct Er er ;
int main()
{
int n ;
scanf("%d",&n) ;
shiliu* a = (shiliu*)malloc(n*sizeof(shiliu)) ;
ba* c = (ba*)malloc(sizeof(ba)) ;
er* b = (er*)malloc(sizeof(er)) ;
for(int i=0;i<n;++i)
scanf("%s",a[i].s) ;
int number = 0 ;
for(int i=0;i<n;++i)
{//16转2 1拆4
number = 0 ;
for(int j=0;a[i].s[j]!='\0';++j)
{
switch(a[i].s[j])
{
case '0':
b->s[number++]='0';b->s[number++]='0';b->s[number++]='0';b->s[number++]='0';
break ;
case '1':
b->s[number++]='0';b->s[number++]='0';b->s[number++]='0';b->s[number++]='1';
break ;
case '2':
b->s[number++]='0';b->s[number++]='0';b->s[number++]='1';b->s[number++]='0';
break ;
case '3':
b->s[number++]='0';b->s[number++]='0';b->s[number++]='1';b->s[number++]='1';
break ;
case '4':
b->s[number++]='0';b->s[number++]='1';b->s[number++]='0';b->s[number++]='0';
break ;
case '5':
b->s[number++]='0';b->s[number++]='1';b->s[number++]='0';b->s[number++]='1';
break ;
case '6':
b->s[number++]='0';b->s[number++]='1';b->s[number++]='1';b->s[number++]='0';
break ;
case '7':
b->s[number++]='0';b->s[number++]='1';b->s[number++]='1';b->s[number++]='1';
break ;
case '8':
b->s[number++]='1';b->s[number++]='0';b->s[number++]='0';b->s[number++]='0';
break ;
case '9':
b->s[number++]='1';b->s[number++]='0';b->s[number++]='0';b->s[number++]='1';
break ;
case 'A':
b->s[number++]='1';b->s[number++]='0';b->s[number++]='1';b->s[number++]='0';
break ;
case 'B':
b->s[number++]='1';b->s[number++]='0';b->s[number++]='1';b->s[number++]='1';
break ;
case 'C':
b->s[number++]='1';b->s[number++]='1';b->s[number++]='0';b->s[number++]='0';
break ;
case 'D':
b->s[number++]='1';b->s[number++]='1';b->s[number++]='0';b->s[number++]='1';
break ;
case 'E':
b->s[number++]='1';b->s[number++]='1';b->s[number++]='1';b->s[number++]='0';
break ;
case 'F':
b->s[number++]='1';b->s[number++]='1';b->s[number++]='1';b->s[number++]='1';
break ;
}
b->s[number]='\0' ;
}
// printf("2进制%s\n",b->s) ;
//2转8
number = 0 ;
int sum = strlen(b->s) ;
// for(int j=0;b[i].s[j]!='\0';++j)
// ++sum ;
int j ;
if(sum%3==0)
j = 0 ;
else if(sum%3==1)
j = -2 ;
else
j = -1 ;
while(j<sum) //b->s[j]!='\0'
{
char temp[4] ;
if(j==-2)
{
temp[0]='0';temp[1]='0'; j=0; temp[2]=b->s[j++] ; temp[3]='\0' ;
}
else if(j==-1)
{
temp[0]='0'; j=0; temp[1]=b->s[j++]; temp[2]=b->s[j++] ; temp[3]='\0' ;
}
else
{
temp[0]=b->s[j++];temp[1]=b->s[j++];temp[2]=b->s[j++];temp[3]='\0';
}
if(strcmp(temp,"000")==0)
c->s[number++]='0';
else if(strcmp(temp,"001")==0)
c->s[number++]='1';
else if(strcmp(temp,"010")==0)
c->s[number++]='2';
else if(strcmp(temp,"011")==0)
c->s[number++]='3';
else if(strcmp(temp,"100")==0)
c->s[number++]='4';
else if(strcmp(temp,"101")==0)
c->s[number++]='5';
else if(strcmp(temp,"110")==0)
c->s[number++]='6';
else if(strcmp(temp,"111")==0)
c->s[number++]='7';
c->s[number]='\0' ;
// printf("8进制%s\n",c->s) ;
}
int sign = 0 ;
for(int k=0;;++k)
{
if(c->s[k]!='0')
{
sign = k ; break ;
}
}
for(int k=sign;c->s[k]!='\0';++k)
printf("%c",c->s[k]) ;
printf("\n") ;
b->s[0]='\0' ; c->s[0]='\0' ;
}
free(c) ; free(b) ;
return 0 ;
}
欢迎讨论交流。