蓝桥杯 【基础练习】 十六进制转八进制

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

一般的思路是将十六进制转换为十进制,然后转换为八进制.

一段示例代码:

#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
long long hex_to_dec(string hex)
{
    long long dec = 0;   
    int len = hex.length();  
    for(int i=0 ;i<len;i++)  
    {  
        if(hex[i] >= 'A')  
        {  
            dec += (hex[i] - 'A' + 10)*pow(16,len-1-i);   
        }  
        else  
        {  
            dec += (hex[i] - '0')*pow(16,len-1-i);  
        }  
    }  
    return dec;  
}
void dec_to_oct(long long dec)
{
	char a[100];   
    long long s = dec;  
    int i = 0;  
    while(s/8 != 0)  
    {  
        a[i++] = '0' + s%8;   
        s = s/8;  
    }  
    a[i] = '0' + s; 
	while(i>=0)
	{
		cout<<a[i--];
	}
}
int main()
{
	string str[10];
	int n;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cin>>str[i];
	} 
	for(int i=0;i<n;i++)
	{
	 	dec_to_oct(hex_to_dec(str[i]));
	 	cout<<endl;
	}
	return 0;
}

如果提交上面的代码系统会判定代码错误,因为题目中有一句话:每个十六进制数长度不超过100000。这句话说明该十六进制数有可能是一个长度为100000的数,这不是long long 类型变量所能表示的,这应该就是错误所在。


做大数运算的常用手段就是字符串变量,这里我们使用字符串变量来表示对应的二进制数,得到下面的解法:

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
	string hex[10];
	string bin[10];
	string oct[10];
	int n;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cin>>hex[i];
	} 
	//16进制转2进制
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<hex[i].length();j++)
		{
			switch(hex[i][j])
			{
				case '0':bin[i] += "0000";break;
				case '1':bin[i] += "0001";break;
				case '2':bin[i] += "0010";break;
				case '3':bin[i] += "0011";break;
				case '4':bin[i] += "0100";break;
				case '5':bin[i] += "0101";break;
				case '6':bin[i] += "0110";break;
				case '7':bin[i] += "0111";break;
				case '8':bin[i] += "1000";break;
				case '9':bin[i] += "1001";break;
				case 'A':bin[i] += "1010";break;
				case 'B':bin[i] += "1011";break;
				case 'C':bin[i] += "1100";break;
				case 'D':bin[i] += "1101";break;
				case 'E':bin[i] += "1110";break;
				case 'F':bin[i] += "1111";break;
				default :break;
			}
		}
	} 
	//2进制转8进制
	for(int i=0;i<n;i++)
	{
		int len = bin[i].length();
		int num = 0;
		int temp = 3;
		for(int j=len-1;j>=0;j--)
		{
			if(bin[i][j] == '1') 
			{
				switch(temp)
				{
					case 3: num +=1;break;
					case 2: num +=2;break;
					case 1: num +=4;break;
					default:break;
				}
			}
			temp--;
			if(temp == 0)
			{
				oct[i] += num + '0';
				num = 0;
				temp = 3; 
			}			
		}
		if(temp != 0)
		{
			oct[i] += num + '0'; 
		}
	} 
	//对8进制数逆序
	for(int i=0;i<n;i++)
	{
		char temp;
		int len = oct[i].length();
		for(int j=0;j<len/2;j++)
		{
			temp = oct[i][j];
			oct[i][j] = oct[i][len-1-j];
			oct[i][len-1-j] = temp; 
		}
	} 
	//输出数据
	for(int i=0;i<n;i++)
	{
		 int len = oct[i].length();
		 int j=0;
		 while(oct[i][j++] == '0');
		 for(--j;j<len;j++)
		 {
		 	cout<<oct[i][j];
		 }
		 cout<<endl;
	} 
	return 0;
} 



  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值