藍橋杯練習系統 基礎練習:BASIC-12 十六進制轉八進制

題目信息

問題描述

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

輸入格式

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

輸出格式

 輸出n行,每行爲輸入對應的八進制正整數。
 【注意】
輸入的十六進制數不會有前導0,比如012A。
輸出的八進制數也不能有前導0。

樣例輸入

 2
 39
 123ABC

樣例輸出

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

解題思路

主要考察

 本題給出的考察關鍵字爲進制轉換、字符、循環。看到這個題我首先想到的是將十六進制轉換爲十進制,然後再將十進制裝換爲八進制。如果你也這麼想,恭喜你!你也想錯了!注意:每個十六進制數長度不超過100000,如果轉爲十進制不管是用java還是C++,都會出現數據溢出的情況,即使是long long也不可以。第一遍解這個題目我就是按照這個思路做的,結果寫完測了測題目給出的測試樣例發現過了,結果交到藍橋杯官網測試的時候是0分。。。
流下了沒技術的淚水
其實看題目給出的關鍵字我們就應該明白這個題目真正考察的是字符串。正確的做法是將十六進制轉換爲二進制,然後再將二進制轉換爲八進制。。那麼十六進制怎樣轉換爲二進制呢?需要使用:取一分四法:將十六進制的每一位數轉換成四位二進制數,不足四位數則在前面補0。也許你會感到疑惑,爲什麼要這樣轉換?原因是:

 二進制和十六進制都是通過輾轉相除求餘得到的,所以每除4次2,就可以得到4位的二進制數據,相當於除16得到的1位16進制數據。這就是4對1的來由。

十六進制轉二進制
八進制轉換爲二進制是取三合一法,即取三位二進制數作爲一位八進制數。

解題思路

 首先將十六進制按照上述的方法轉換爲二進制,然後不斷的將轉換出來的數使用==append()方法存到一個字符串中。遍歷這個字符串,使用substr()==方法三位三位的截取字符串與三位二進制數比較,然後將結果append()到一個字符串中,最後輸出字符串即可。還有一個很重要的點是最後一定不要忘記去除前導0,如果不去除前導0結果也是錯誤的。

解題代碼

#include<iostream>
#include<string>
using namespace std;

int main(){
	int n;
	string Hex_num[10];
	cin>>n;
	cin.ignore();
	//輸入十六進制數 
	for(int i=0;i<n;i++){
		getline(cin,Hex_num[i]);
	}
	//十六進制表
	string Hexs[16] = {"0", "1", "2", "3", "4", "5", "6", "7", 
			           "8", "9", "A", "B", "C", "D", "E", "F"};
	//二進制表 
	string Bins[16] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", 
			           "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
	//八進制表
	string Octs[8] = {"0", "1", "2", "3", "4", "5", "6", "7"};
	for(int i=0;i<n;i++){
		//將十六進制轉換爲二進制
		string Bin_num;
		int len = Hex_num[i].size();
		//將十六進制數的每一位轉換爲四位二進制數
		for(int j=0;j<len;j++){
			char x = Hex_num[i].at(j);
			string Bin;
			if(x >= 'A' && x <= 'F'){
				Bin = Bins[x-'A'+10];
			}else{
				Bin = Bins[x-'0'];
			} 
			Bin_num.append(Bin);
		}
		//cout<<Bin_num<<endl;
		//將二進制轉換爲八進制
		/*注意:二進制轉換爲八進制是每三位二進制數對應一位八進制數。
		需要使二進制的個數爲3的整數倍,否則需要在二進制數前面加前導 0
		使其個數爲3的整數倍 
		*/ 
		int bin_count = Bin_num.size();
		if(bin_count%3==1){
			Bin_num = "00" + Bin_num;
		}
		if(bin_count%3==2){
			Bin_num = "0" + Bin_num;
		}
		//cout<<Bin_num<<endl;
		//補完前導0之後將二進制轉換爲八進制
		len = Bin_num.size();
		string Oct_num;
		for(int k=0;k<len;k += 3){
			//截取子串 
			string b = Bin_num.substr(k,3);
			if(b == "000"){
				Oct_num.append("0");
			}else if(b == "001"){
				Oct_num.append("1");
			}else if(b == "010"){
				Oct_num.append("2");
			}else if(b == "011"){
				Oct_num.append("3");
			}else if(b == "100"){
				Oct_num.append("4");
			}else if(b == "101"){
				Oct_num.append("5");
			}else if(b == "110"){
				Oct_num.append("6");
			}else if(b == "111"){
				Oct_num.append("7");
			}
		} 
		//去除前導0
		if(Oct_num[0] == '0'){
			Oct_num.erase(Oct_num.begin());
		} 
		cout<<Oct_num<<endl;	 
	} 
	
	return 0;
		
} 

 以上就是對於本題的解題思路了,如果你覺得我的文章對你有用請點個贊支持一下吧,如果喜歡我寫的文章那麼請點個關注再走呦。如果此文章有錯誤或者有不同的見解歡迎評論或者私信。
衝鴨
我是ACfun:一個成長中的程序猿,感謝大家的支持。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章