2018藍橋杯|基礎練習|十六進制轉八進制


問題描述
  給定n個十六進制正整數,輸出它們對應的八進制數。

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

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

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

樣例輸入
  2
  39
  123ABC

樣例輸出
  71
  4435274

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

思路來源:http://blog.csdn.net/b1055077005/article/details/54562345

思路:首先把十六進制數轉成二進制數,方法:每一個輸入的十六進制數保存為字符串類型(string)然后用一個switch 把十六進制的每一個數對應到正確的四位二進制數上 字符串連接用+=。這樣就得到了十六進制數的二進制形式,轉八進制只需三個三個一組。但這時必須要判斷當前的而進制串是否能被三整除,若不能,應在最前面適當的補0。之后我們就可以每三個數得到一個0~7之間數,這里也必須按照ASCII碼的方式算(注意:‘0’的ASCII不是0)。然后要觀察得到的八進制數最前面是否有零,若有,要去掉。最后,每個結果輸出后要換行。

我的代碼:

#include<iostream>
#include<string>
using namespace std;
int main(){
    int n=0;
    cin>>n;
    string shiliu,er,ba;
    for(int j=0;j<n;j++){
        er="";
        ba="";
        cin>>shiliu;
        for(int i=0;i<shiliu.size();i++){
        //    er="";
        //    ba="";錯誤1 
            switch(shiliu[i]){
                case '0' : er+="0000";break;
                case '1' : er+="0001";break;
                case '2' : er+="0010";break;
                case '3' : er+="0011";break;
                case '4' : er+="0100";break;
                case '5' : er+="0101";break;
                case '6' : er+="0110";break;
                case '7' : er+="0111";break;
                case '8' : er+="1000";break;
                case '9' : er+="1001";break;
                case 'A' : er+="1010";break;
                case 'B' : er+="1011";break;
                case 'C' : er+="1100";break;
                case 'D' : er+="1101";break;
                case 'E' : er+="1110";break;
                case 'F' : er+="1111";break;
                default:break;
            }
        } 
        int length=er.size();
        if(length%3==1) {
            er="00"+er;length+=2;
        }
        else if(length%3==2) {
            er="0"+er;length++;
        }
        for(int k=0;k<length;k+=3){
            int d=4*(er[k]-'0')+2*(er[k+1]-'0')+(er[k+2]-'0');
            ba+=(d+'0');
        //    ba+=4*er[k]+2*er[k+1]+er[k+2]; 錯誤2 
        }
        /*for(int p=0;p<ba.size();p++){
        //    if(ba[p]=='0')continue;//錯誤3 
        //    cout<<ba[p];
        while(ba[p]=='0')p++;
        cout<<ba[p]; 錯誤4  思路不對 
        }*/
        int p=0;
        while(ba[p]=='0')p++;
        for(p;p<ba.size();p++)
            cout<<ba[p];
        cout<<endl;//敲里嗎 一直不通過就因為沒有這一句 
    }
    return 0;     
}

注意事項:

1.初始化的位置。一開始我把對八進制數和二進制數的初始化錯放在內層循環的里面,本應是四位四位二進制數的串接,但我確實得到四位便清空,再得到四位又清空......

2.當一個數字是char型的或者string型的,數字的相加就變成了ASCII碼的相加。而我們知道數字0的ASCII碼值不為0,而是48,因此我們計算1+2得到的結果是99(1的ASCII是49,2的ASCII是50)。因此若是直接的 ba+=4*er[k]+2*er[k+1]+er[k+2]; 就加多了。因此要按照代碼中方式來寫:增加的數值是原數減去0的ASCII的差值,最后再加上0的ASCII,才是正確答案數字對應的ASCII。

3.得到的八進制數是否最前面有零 不是通過一個簡單的遍歷整個字符串出現0就continue得到的。因為這樣會把所有的0都continue掉。而且while循環和for循環的嵌套關系要是寫反也會導致很嚴重的錯誤。for(int p=0;p<ba.size();p++){ while(ba[p]=='0')p++; cout<<ba[p];  }這樣寫就錯了,因為第一次執行while循環就已經使p的位置達到了真正的首個高位數字的位置,再執行for循環就不應該再走while循環了。因此while循環應該放在for循環的外面。

4.藍橋杯系統及其嚴格:輸出格式若是一個輸出一個換行的話,必須要在程序中寫這個換行!!不然一定0分!!return 0;也必須要寫!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM