問題描述
給定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;也必須要寫!!!