【藍橋訓練系統---十六進制轉換成八進制】字符&&循環&&進制轉換

題目鏈接:Click here here

基礎練習 十六進制轉八進制
時間限制:1.0s 內存限制:512.0MB
問題描述
  給定n個十六進制正整數,輸出它們對應的八進制數。

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

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

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

樣例輸入
  2
  39
  123ABC

樣例輸出
  71
  4435274

  【提示】
  先將十六進制數轉換成某進制數,再由某進制數轉換成八進制。

思路:先將十六進制轉換成二進制,再轉換成八進制。
一位十六進制位對應四位二進制位,三位二進制位對應一位八進制位。
輸入的十六進制用字符型,字符串輸入哦;由於一個十六進制位依次對2取餘,得到的第一個餘數在最右邊,最後一個餘數在最左邊,所以可以採用倒序轉換的方法。這樣依次取得的餘數正序存儲到二進制數組中。二進制數組可採用整型或字符型。
十六進制轉換成二進制的代碼如下:

int j,k=0,i;
for(i=len1-1;i>=0;i--)//倒序,得到十六進制對應的二進制數組 
{
    j=4;
    int flag;
    if(strD[i]>='0'&&strD[i]<='9')
        flag=strD[i]-'0';
    else if(strD[i]>='A'&&strD[i]<='Z')
        flag=strD[i]-'A'+10;    
    while(j--)          //一位十六進制對應四位二進制,連除四次,保留餘數 
    {
        strB[k++]=(flag%2)+'0';  
        flag>>=1;
    }
} 

正常的順序中二進制轉換成八進制是左邊最高位乘以4,右邊最低位乘以1,,倒序存儲時,左側最高位乘以1,右側最低位乘以4。
法一:
正序轉換,倒序輸出,不含前導0,注意二進制數組是整型和字符型的操作不同哦,若char strB[];memset(strB,0,sizeof(strB));則全部賦值爲空,而不是字符型的‘0’;char strB[]={‘0’},只有第一個賦值爲字符型的‘0’,其他全部爲空哦。
整型數組代碼如下(轉換成的八進制數組也是整型哦):

int p=0;
for(i=0;i<k;i+=3)       //三位二進制位對應一位八進制位, 
        strH[p++]=strB[i]+strB[i+1]*2+strB[i+2]*4;//正序的話,左側最高位權值最高,現在倒序,左側權值最低了哦 
for(i=p-1;i>=0;i--)//倒序輸出對應的八進制位哦 
{
    if(strH[i]==0)  //不含前導0,所以遇0不輸出哦 
        continue;
    else
    {
        for(j=i;j>=0;j--)
            printf("%d",strH[j]);
        break;
    }       
}

字符型代碼如下:

int p=0;
for(i=0;i<k;i+=3)       //三位二進制位對應一位八進制位, 
{
    if(k-i==2)
        strB[i+2]='0';
    else if(k-i==1)
        strB[i+1]=strB[i+2]='0';
    strH[p++]=(strB[i]-'0'+(strB[i+1]-'0')*2+(strB[i+2]-'0')*4)+'0';
}
//正序的話,左側最高位權值最高,現在倒序,左側權值最低了哦 
for(i=p-1;i>=0;i--)//倒序輸出對應的八進制位哦 
{
    if(strH[i]=='0')    //不含前導0,所以遇0不輸出哦 
        continue;
    else
    {
        for(j=i;j>=0;j--)
            printf("%c",strH[j]);
        break;
    }       
}

倒序轉換,由於二進制的位數不一定是3的整數倍,所以可先將長度轉換成3的整數倍,即最後不足3的整數倍的位數補0(整型數組,字符型補字符型‘0’);
整型代碼如下:

k=k+3-k%3;          //將二進制數組長度更新成3的倍數 
k--;                //二進制數組從0開始呢 
while(strB[k]*4+strB[k-1]*2+strB[k-2]==0)
    k-=3;               //不含前導0,則將結果是0的部分去掉,即k直接向前跳呢 
for(i=k;i>0;i-=3)       //倒序輸出  
{
    int ans=strB[i]*4+strB[i-1]*2+strB[i-2];
    printf("%d",ans);
}

整體代碼:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char strD[100000+11];           //輸入十六進制 ,用字符型 
int strB[400000+11];            //十六進制對應二進制數,可用整型存儲 
int strH[300000+11];            //二進制對應八進制數,用整型存儲 
int main()
{   
    int n;
    scanf("%d",&n);
    while(n--)
    {
        memset(strB,0,sizeof(strB));
        scanf("%s",strD);
        int len1=strlen(strD);
        if(strD[0]=='0'&&len1==1)       //輸入只有一個0,那麼直接就輸出0咯 
        {
            printf("0\n");
            continue;
        }
        int j,k=0,i;
        for(i=len1-1;i>=0;i--)//倒序,得到十六進制對應的二進制數組 
        {
            j=4;
            int flag;
            if(strD[i]>='0'&&strD[i]<='9')
                flag=strD[i]-'0';
            else if(strD[i]>='A'&&strD[i]<='Z')
                flag=strD[i]-'A'+10;    
            while(j--)          //一位十六進制對應四位二進制,連除四次,保留餘數 
            {
                strB[k++]=(flag%2);  
                flag>>=1;
            }
        } 
        int p=0;
        for(i=0;i<k;i+=3)       //三位二進制位對應一位八進制位, 
            strH[p++]=strB[i]+strB[i+1]*2+strB[i+2]*4;//正序的話,左側最高位權值最高,現在倒序,左側權值最低了哦 
        for(i=p-1;i>=0;i--)//倒序輸出對應的八進制位哦 
        {
            if(strH[i]==0)  //不含前導0,所以遇0不輸出哦 
                continue;
            else
            {
                for(j=i;j>=0;j--)
                    printf("%d",strH[j]);
                break;
            }       
        }
    /*  k=k+3-k%3;          //將二進制數組長度更新成3的倍數 
        k--;                //二進制數組從0開始呢 
        while(strB[k]*4+strB[k-1]*2+strB[k-2]==0)
            k-=3;               //不含前導0,則將結果是0的部分去掉,即k直接向前跳呢 
        for(i=k;i>0;i-=3)       //倒序輸出  
        {
            int ans=strB[i]*4+strB[i-1]*2+strB[i-2];
            printf("%d",ans);
        }*/
        printf("\n");
    }
    return 0;
}
發佈了88 篇原創文章 · 獲贊 18 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章