蓝桥杯练习系统 基础练习: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结果也是错误的。

扫描二维码关注公众号,回复: 11072999 查看本文章

解题代码

#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:一个成长中的程序猿,感谢大家的支持。

发布了87 篇原创文章 · 获赞 263 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_41575507/article/details/105703517