蓝桥杯 基础练习 十六进制转八进制 C++实现

题目:

资源限制

内存限制:512.0MB   C/C++时间限制:1.0s   Java时间限制:3.0s   Python时间限制:5.0s

问题描述
  给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
  输入的第一行为一个正整数n (1<=n<=10)。
  接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
  输出n行,每行为输入对应的八进制正整数。
  【注意
  输入的十六进制数不会有前导0,比如012A。
  输出的八进制数也不能有前导0。
样例输入
  2
  39
  123ABC
样例输出
  71
  4435274
  提示
  先将十六进制数转换成某进制数,再由某进制数转换成八进制。

思路:

在小编看见这个题的时候一下子就想到了用输出流控制符来解决,就像这样:

    cin >>hex >> num;
    cout << oct << num <<endl;

很显然是小编轻敌了,这题远没有想象的那么简单,再看题干“每个十六进制数长度不超过100000”,这句话非常重要,题干的意思是输入的十六进制字符有十万位,这显然是一个非常大的数,利用输出流控制符的话1s的运行时间一定是不够的,所以我们先将16进制转换成2进制然后再对二进制分为3位一组进行转换。

算法实现:

首先我们可以把数字输入改写成字符串输入这样可以利用switch语句进行转换就像这样:

string trans_bin(string s)
{
	string s_bin = "";
	for (int i = 0; i < s.length(); ++i)
	{
		switch (s[i])
		{
		case '0': s_bin += "0000"; break;
		case '1': s_bin += "0001"; break;
		case '2': s_bin += "0010"; break;
		case '3': s_bin += "0011"; break;
		case '4': s_bin += "0100"; break;
		case '5': s_bin += "0101"; break;
		case '6': s_bin += "0110"; break;
		case '7': s_bin += "0111"; break;
		case '8': s_bin += "1000"; break;
		case '9': s_bin += "1001"; break;
		case 'A': s_bin += "1010"; break;
		case 'B': s_bin += "1011"; break;
		case 'C': s_bin += "1100"; break;
		case 'D': s_bin += "1101"; break;
		case 'E': s_bin += "1110"; break;
		case 'F': s_bin += "1111"; break;
		}
	}
	return s_bin;
}

这样我们就把十六进制转换成了二进制了,然后我们利用三个字符一组将二进制转换成八进制,

这里我们用到了substr(a,b )函数,这个函数可以用来截取从a开始到后面b位的字符。

代码如下

for (int i = 0; i < s.length(); i += 3)
{
	if (s4.substr(i, 3) == "000")s1 += "0";	
	else if (s4.substr(i, 3) == "001")s1 += "1";
	else if (s4.substr(i, 3) == "010")s1 += "2";
	else if (s4.substr(i, 3) == "011")s1 += "3";
	else if (s4.substr(i, 3) == "100")s1 += "4";
	else if (s4.substr(i, 3) == "101")s1 += "5";
	else if (s4.substr(i, 3) == "110")s1 += "6";
	else if (s4.substr(i, 3) == "111")s1 += "7";
}

但是我们要知道这二进制字符不一定是三的整数倍,所以我们需要对数组进行倒叙并且再空位补上0然后在恢复原有顺序,具体代码如下:

string trans_oct(string s)
{
	string print_s = "", re_s = "", s_temp = "";
	for (int j = s.length() - 1; j >= 0; j--)
	{
		re_s += s[j];
	}
	if (re_s.length() % 3 != 0)
	{
		for (int i = 0; i < (3 - s.length() % 3); i++)
		{
			re_s += "0";
		}
	}
	for (int j = re_s.length() - 1; j >= 0; j--)
	{
		s_temp += re_s[j];
	}
	for (int i = 0; i < re_s.length(); i += 3)
	{
		if (s_temp.substr(i, 3) == "000")print_s += "0";
		else if (s_temp.substr(i, 3) == "001")print_s += "1";
		else if (s_temp.substr(i, 3) == "010")print_s += "2";
		else if (s_temp.substr(i, 3) == "011")print_s += "3";
		else if (s_temp.substr(i, 3) == "100")print_s += "4";
		else if (s_temp.substr(i, 3) == "101")print_s += "5";
		else if (s_temp.substr(i, 3) == "110")print_s += "6";
		else if (s_temp.substr(i, 3) == "111")print_s += "7";
	}
	if (print_s.substr(0, 1) == "0")
		print_s = print_s.substr(1, print_s.length() - 1);
	return print_s;
}

以上就是该算法的核心部分,接下来只需要按照输入输出要求完成剩余代码即可。

完整代码:

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

string trans_bin(string s)
{
	string s_bin = "";
	for (int i = 0; i < s.length(); ++i)
	{
		switch (s[i])
		{
		case '0': s_bin += "0000"; break;
		case '1': s_bin += "0001"; break;
		case '2': s_bin += "0010"; break;
		case '3': s_bin += "0011"; break;
		case '4': s_bin += "0100"; break;
		case '5': s_bin += "0101"; break;
		case '6': s_bin += "0110"; break;
		case '7': s_bin += "0111"; break;
		case '8': s_bin += "1000"; break;
		case '9': s_bin += "1001"; break;
		case 'A': s_bin += "1010"; break;
		case 'B': s_bin += "1011"; break;
		case 'C': s_bin += "1100"; break;
		case 'D': s_bin += "1101"; break;
		case 'E': s_bin += "1110"; break;
		case 'F': s_bin += "1111"; break;
		}
	}
	return s_bin;
}
string trans_oct(string s)
{
	string s_oct = "", re_s = "", s_temp = "";
	for (int j = s.length() - 1; j >= 0; j--) 
	{
		re_s += s[j];
	}
	if (re_s.length() % 3 != 0)
	{
		for (int i = 0; i < (3 - s.length() % 3); i++)
		{
			re_s += "0";
		}
	}
	for (int j = re_s.length() - 1; j >= 0; j--)
	{
		s_temp += re_s[j];
	}
	for (int i = 0; i < re_s.length(); i += 3)
	{
		if (s_temp.substr(i, 3) == "000")s_oct += "0";
		else if (s_temp.substr(i, 3) == "001")s_oct += "1";
		else if (s_temp.substr(i, 3) == "010")s_oct += "2";
		else if (s_temp.substr(i, 3) == "011")s_oct += "3";
		else if (s_temp.substr(i, 3) == "100")s_oct += "4";
		else if (s_temp.substr(i, 3) == "101")s_oct += "5";
		else if (s_temp.substr(i, 3) == "110")s_oct += "6";
		else if (s_temp.substr(i, 3) == "111")s_oct += "7";
	}
	if (s_oct.substr(0, 1) == "0")
		s_oct = s_oct.substr(1, s_oct.length() - 1);
	return s_oct;
}
int main()
{
	int n;
	cin >> n;
	string s[10];
	string bin, oct;
	for (int i = 0; i < n; ++i)
	{
		cin >> s[i];
	}
	for (int i = 0; i < n; ++i)
	{
		bin = trans_bin(s[i]);
		oct = trans_oct(bin);
		cout << oct << endl;
	}
	return 0;
}

总结:

这道题其实也没有想象中那么复杂,核心部分就是利用分组转换的思想,所以阅读题干给的提示同样重要,同时不要局限于数字方面来思考,转换成字符类型有时候会有更简单的方法!!!!!

  • 12
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郁达夫不会编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值