基础练习 十六进制转八进制

问题描述
  给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
  输入的第一行为一个正整数n (1<=n<=10)。
  接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
  输出n行,每行为输入对应的八进制正整数。
  【注意】
  输入的十六进制数不会有前导0,比如012A。
  输出的八进制数也不能有前导0。
样例输入
  2
  39
  123ABC
样例输出
  71
  4435274
  【提示】
  先将十六进制数转换成某进制数,再由某进制数转换成八进制。

算是一道模拟题吧?(是模拟题吧?因为比较浮躁,理论知识并不扎实,有错的地方还请大家原谅和指出)。
思路是对字符串进行遍历,但因为在二进制转八进制时要判断二进制是否需要前导零,为避免这种判断,我采用倒序遍历。16进制转2进制时,每次遍历1个16进制字符串中的一个字符串,将其转换为10进制数,再用除二取余法求2进制的表示,并倒序保存在2进制表示的数组中。
然后对2进制的数组倒序遍历,每次遍历三个元素,再其8进制表示方法倒序保存在8进制表示的数组中。
PS:看到自己的倒序方法在网上貌似没有,心里偷偷得意。

#include<stdio.h>
#include<string.h>
#include<malloc.h>
#include<math.h>

int* change(char* list, int list_l, int* ret_l){
    int *list_2, *list_8;
    int list_2_l, list_8_l, i, j, k, flag;
    list_2_l = list_l * 4;
    /*判断保存8进制数组的长度*/
    if(list_2_l % 3 == 0) list_8_l = list_2_l / 3;
    else list_8_l = list_2_l / 3 + 1;
    list_2 = (int*)malloc(sizeof(int) * list_2_l);
    list_8 = (int*)malloc(sizeof(int) * list_8_l);
    /*i是16进制数组的下标,j是2进制数组的下标*/
    for(i = list_l - 1, j = list_2_l - 1; i >= 0; i--){
        //flag用于保存16进制这一位10进制的大小
        if(list[i] >= '0' && list[i] <= '9')
            flag = list[i] - '0';
        else
            flag = list[i] - 'A' + 10;
        //16进制每一位用2进制表示需要4位,所以循环4次
        for(k = 0; k < 4; k++){
                list_2[j] = (flag % 2);
                j--;
                flag = flag / 2;
        }
    }     
    i = list_2_l - 1;//2进制数组下标
    j = list_8_l - 1;//8进制数组下标
    while(i >= 0){
        flag = 0;//保存这三位2进制表示的8进制的大小
        //8进制每一位用2进制表示需要3位,所以循环3次
        for(k = 0; k < 3 && i >= 0; k++){
            flag = flag + list_2[i] * pow(2, k);
            i--;
        }
        list_8[j] = flag;
        j--;
    }
    free(list_2);
    *ret_l = list_8_l;
    return list_8;
}

int main()
{
    int n, i, list_l, ret_l, *ret_list;
    //ret_l用于保存放回的8进制数组ret_list的长度
    char list[100000];
    scanf("%d", &n);
    //吸收在上面这个scanf回车,否则会影响到下面的gets方法
    getchar();
    while(n--){
        gets(list);
        list_l = strlen(list);
        ret_list = change(list, list_l, &ret_l);
        /*判断第一个数字是否为零(最多只有可能第一个为零,因为我在二进制转换时采用的是倒序)*/
        for(i = 0; i < ret_l && ret_list[i] ==0; i++);
        for(; i < ret_l; i++) printf("%d", ret_list[i]);
        free(ret_list);
        ret_list = NULL;
        printf("\n");
    }

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值