十六进制转八进制

问题描述
  给定n个十六进制正整数,输出它们对应的八进制数。

输入格式
  输入的第一行为一个正整数n (1<=n<=10)。
  接下来n行,每行一个由09、大写字母AF组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。

输出格式
  输出n行,每行为输入对应的八进制正整数。

【注意】
  输入的十六进制数不会有前导0,比如012A。
  输出的八进制数也不能有前导0。

样例输入
  2
  39
  123ABC

样例输出
  71
  4435274

【提示】
  先将十六进制数转换成某进制数,再由某进制数转换成八进制。

题目分析:
最开始忽略了数量级使用暴力,一下就炸了,仔细看题目发现十六进制数长度有100000,这样用传统的方法肯定不行,我们按照进制转换的思想,先把十六进制数每一位转化成4位二进制数,在把二进制数每三位转化为八进制数。

如十六进制的39 转化为二进制 0011 1001
二进制转化为八进制 00 111 001

这里特别注意,二进制转八进制时应该从后往前,不然会错位,最后对不足三位的做特殊处理。

代码:

#include<iostream>
#include<cstdio>
#include<string.h>
#include<cstring>

using namespace std;

char str[100005],d[16][5] = {"0000","0001","0010","0011",
                             "0100","0101","0110","0111",
                             "1000","1001","1010","1011",
                             "1100","1101","1110","1111"};
char  ba[500005],p[8][4]  = {"000","001","010","011",
                             "100","101","110","111"};

int main()
{
    int n,a[500000],i;

    scanf("%d",&n);

    getchar();

    while(n--)
    {
        gets(str);
        int len = strlen(str), sum = 0,flag = 0;

        for(i = 0; i < len; ++i)
        {
            if(str[i] <= '9' && str[i] >= '0')
                sum = str[i]-'0';
            else
                sum = str[i]-'A'+10;

            strncpy(ba+flag,d[sum],4);

            flag += 4;
        }

        //puts(ba);

        len = flag;

        flag = 0;

        for(i = len-1; i >= 0; i-=3)
        {
            if(i < 2)
            {
                break;
            }
            for(int j = 0; j < 8; ++j)
            {
                if(strncmp(ba+i-2,p[j],3) == 0)
                {
                    a[flag++] = j;
                }
            }
        }

        if(i >= 0)
        {
            if(i == 1)
            {
                if(ba[0] == '0' && ba[1] == '1')
                    printf("1");
                else if(ba[0] == '1' && ba[1] == '0')
                    printf("2");
                else if(ba[0] == '1' && ba[1] == '1')
                    printf("3");
            }
            else
            {
                if(ba[0] == '1')
                {
                    printf("1");
                }
            }
        }

        for(int i = flag-1; i >= 0; --i)
        {
            printf("%d",a[i]);
        }


        printf("\n");
    }


    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值