1. 程式人生 > >超長的十六進位制數轉換為八進位制

超長的十六進位制數轉換為八進位制

之前在oj上做過,今天做藍橋杯基礎練習又遇到了這題
but沒有一遍AC
基礎練習 十六進位制轉八進位制
時間限制:1.0s 記憶體限制:512.0MB
提交此題 錦囊1 錦囊2
問題描述
  給定n個十六進位制正整數,輸出它們對應的八進位制數。

輸入格式
  輸入的第一行為一個正整數n (1<=n<=10)。
  接下來n行,每行一個由09、大寫字母AF組成的字串,表示要轉換的十六進位制正整數,每個十六進位制數長度不超過100000。

輸出格式
  輸出n行,每行為輸入對應的八進位制正整數。

【注意】
  輸入的十六進位制數不會有前導0,比如012A。
  輸出的八進位制數也不能有前導0。

樣例輸入
  2
  39
  123ABC

樣例輸出
  71
  4435274

【提示】
  先將十六進位制數轉換成某進位制數,再由某進位制數轉換成八進位制。
  AC程式碼:

#include <stdio.h>
#include <string.h>
#include <math.h>
char a[100002];
int b[400005],c[200002];
int k;
void add_0(int len)
{
    int z = 4*len%3;//沒位16進位制可以用4位二進位制表示
    k = 3 - z;
    /*
    k為化為二進位制後應該補的零個數,
    因為之前初始化已經全是0,
    所以之後的二進位制數只要從k開始存就行。
    */
}
//十六進位制字元化為10進位制數字
int num_16(char a)
{
    if(a >= 'A')
        return a - 'A' + 10;
    else
        return a - '0';
}
//每個10進位制化為2進位制
void num_2(int len)
{
    for(int i = 0; i < len; i++)
    {
        int f = 3,y = num_16(a[i]),t;
        //核心部分,可以自己演示一遍
        while(f >= 0)
        {
            t = y/pow(2,f);
            if(t)
            {
                b[k++] = 1;
            }
            else
            {
                b[k++] = 0;
            }
            y %= (int)pow(2,f);
            f--;
        }
    }
}
//列印8進位制數
void print_8()
{
    int j = 0,m = 0;
    //每三位一個8進位制數
    for(int i = 2; i < k; i+=3)
    {
        c[j++] = b[i] + b[i-1]*2 + b[i-2]*4;
    }
    //去掉前置0
    while(c[m]==0)
    {
        m++;
    }
    for(int i = m; i < j; i++)
        printf("%d",c[i]);
    printf("\n");
}
int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
    {
        memset(a,'\0',sizeof(a));
        memset(b,0,sizeof(b));
        memset(c,0,sizeof(c));
        scanf("%s",a);
        int len = strlen(a);
        k = 0;//這個要注意,不要放外面去了
        add_0(len);
        num_2(len);
        print_8();
    }
    return 0;
}