蓝桥杯 十六进制转八进制
问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
【提示】
先将十六进制数转换成某进制数,再由某进制数转换成八进制。
/* 这是我摘抄的一篇 我感觉比我写的更好 */ #include <stdio.h> #include <stdlib.h> #include <string.h> /* 将十六进制字符转换为数值 */ int get_value(const char c) { if (c >= '0' && c <= '9') return c - '0'; else return c - 'A' + 10; } int main() { char *input, *output, *output2, *ptr; int n, i, j, tmp, len; scanf("%d\n", &n); input = (char *)malloc(100000+1);/* 储存输入的十六进制数 */ output = (char *)malloc(100000*4+4);/* 储存过度用的二进制数 */ output2 = (char *)malloc(100000*3+3);/* 储存最终结果八进制数 */ while(n--) { gets(input); len = strlen(input); ptr = input; j=0; while(*ptr) { tmp = get_value(*ptr); output[j++] = ((tmp>>3)&0x1); output[j++] = ((tmp>>2)&0x1); output[j++] = ((tmp>>1)&0x1); output[j++] = ((tmp>>0)&0x1); ptr ++; } /* 将二进制转换为八进制,3位二进制数对应1位八进制数,从低位开始转 */ /* j为二进制数组下标,每个循环减3 */ /* i为八进制数组下标,每个循环减1 */ j=len*4-1; i=(len*4+2)/3 - 1; output2[i+1] = '\0'; for(;j>=0;) { if(j >= 2) output2[i--] = (output[j-2]<<2 | output[j-1]<<1 | output[j]) + '0'; else if (j == 1) output2[i--] = (output[j-1]<<1 | output[j])+'0'; else if (j == 0) output2[i--] = output[j]+'0'; j -= 3; } /* 八进制数组的有效下标从 i+1 开始 */ j = i+1; /* 去除前导的'0'字符(可能会影响判定结果) */ while(output2[j]=='0') j++; /* 如果整个字符串都是'0',则直接输出结果'0',否则从首位非'0'开始输出 */ if( output2[j] == '\0') printf("0\n"); else printf("%s\n", &output2[j]); } free(input); free(output); free(output2); return 0; }