蓝桥杯C/C++ 基础练习 十六进制转八进制 C语言

题目:

在这里插入图片描述

分析:

思路:先将十六进制转为二进制,然后将二进制转为八进制

遇到的问题如下:

1、输入格式和输出格式,决定了需要用数组存储十六进制数、二进制数以及八进制数。由于有多个字符串(多位十六进制数),故采用二维数组。
2、十六进制数由数字和字母“A/B/C/D/E/F”组成,在将十六进制转为二进制时,需要先判断十六进制数每一位是数字还是字母,并转化为十进制,再转为二进制(按位转化),并存储到二进制数组中。
3、需要注意是从后往前展开,举例:输入十六进制数:2A(0010 1010),存放到二进制数组的顺序相反:0101 0100,在将二进制转化为八进制的时候,仍然是倒序放入,输出时则从后往前,得出的即为正序。
4、二进制转八进制的过程:把二进制数组中每三位计算出来,依次到八进制数组中。对应的公式:num = 2^0 * A + 2^1 * B +2^2 * C。上述的A、B、C分别为二进制数组字符串中的每一位,即0或1。
5、那么如何判断每三位一组且循环相加呢?部分代码如下:
在这里插入图片描述

注意,此处利用每一位相乘的权值来判断是否计算了三位,第三位权值为4,所以用cnt==4来判断。而j==m-1是防止剩余不足三位。求和放到八进制数组中(倒序),由于为倒序,打印时也应该为倒序打印;
6、尽管用的是二维数组,但是由于在整个大循环中,用法和一维数组一样。需要注意的是:定义数组时,每个字符串长度要满足题目条件,每个十六进制数长度不超过100000。

代码如下:
运行环境:Code::Block 20.03

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

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

int main(void)
{
    int n, i, j, k;
    scanf("%d", &n);
    char h[n][100000];
    char b[n][400000];
    char e[n][400000];

    for(i = 0; i < n; i++)
    {
        scanf("%s",h[i]);
    }

    for(i = 0; i < n; i++)// 第一层循环:将每个字符串都化为二进制数,存放到b[i][m]中,m用来记录存放了对应字符串的长度
    {
        int m = 0;
        for(j = strlen(h[i]) - 1; j >= 0; j--)
        {
            int num;
            if(h[i][j] >= '0' && h[i][j] <= '9')
            {
                num = h[i][j] - '0';
            }else{
                num = h[i][j] - 'A' + 10;
            }
            for(k = 0; k < 4; k++)
            {
                b[i][m++] = num % 2 + '0';
                num /= 2;
            }

            b[i][m] = '\0';
        }

//        //测试是否成功转化为二进制(从后往前展开),并存放到b[i][m]中
//        for(j = 0; j < m; j++)
//        {
//            printf("%c", b[i][j]);
//        }
//        printf("\n");


        //将b[i]中的每个字符串每三位计算出来,存放到e[i][l]数组中
        int x = 0, cnt = 1, l = 0;
        for(j = 0; j < m; j++)
        {
            if(cnt == 4 || j == m - 1)
            {
                x = cnt * ( b[i][j] - '0') + x;
                e[i][l] = x + '0';           //由于定义e[][]为字符数组,所以需要+'0'字符转化一下
                l++;
                cnt = 1;
                x = 0;
            }else{
                x = cnt * ( b[i][j] - '0') + x;
                cnt *= 2;
            }

        }

        j = l - 1;
        while(j >= 0 && e[i][j] == '0')        //题目规定不能有前导0,e[][]数组中是倒序存入,故从后往前判断是否为0
        {
            j--;
        }
        if(j < 0)                              //如果全为0则输出为0
        {
            printf("0");
        }
        for(; j >= 0; j--)                     //否则循环输出(输出为正序)
        {
            printf("%c", e[i][j]);
        }
        printf("\n");

    }


    return 0;
}
                                //菜鸟一枚,请多指正!
                          		
                          		        End
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值