蓝桥杯 十六进制转八进制

资源限制

时间限制:1.0s 内存限制:512.0MB

问题描述

给定n个十六进制正整数,输出它们对应的八进制数。

输入格式

输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由09、大写字母AF组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。

输出格式

输出n行,每行为输入对应的八进制正整数。

【注意】
  输入的十六进制数不会有前导0,比如012A。
  输出的八进制数也不能有前导0。

样例输入

2
39
123ABC

样例输出

71
4435274

【提示】
  先将十六进制数转换成某进制数,再由某进制数转换成八进制。

解题思路

  • 选取一个中间进制数,其幂能转化为十六和八,即为二( 其幂能转化为十六和八,这样就可以对每个单独的数拆分为一定数量的中间进制的数)
    1. 比如十六进制可以拆分为四个二进制
    2. 比如八进制可以拆分为三个二进制
  • 十六进制转二进制,从前向后转,每次转四个二进制数
  • 二进制转八进制,从后向前读,每次读三个二进制转化为一个八进制数,不够的话继续往后读(读到的也是0,即补零)
  • 特殊:将十六进制转化为四个二进制,不一定能均分三个将其转化为八进制
    1. 比如
      例子流程

    2. 极端情况下,十六进制转化为二进制头部为0001。并且选取的三个数据转为八进制,所以最多补2个0。此时头部极端情况为00 0001,即(000 001).此时我们可以看到,即使是极端情况下也就是只有头部一个数数据为0,所以此时我们只需要判断头部是不是0,来判断是否输出头部即可,而不需要再对其进行判断。

代码

#include<iostream>
#include<math.h>
#include<string.h>
using namespace std;
char a[15][100000];//char类型数组存储输入数据 
bool b[400010];//bool型数组用来存储二进制数 
char c[200000];//c用来存储转化为八进制的数据 
int main(){
	int n;//输入n 
	cin>>n;
	for(int i=0;i<n;i++) cin>>a[i];
	//num值用来存放临时数据,l存放数据长度,t是转化为二进制的长度 
	int num,l,t; 
	for(int i=0;i<n;i++){
		l=strlen(a[i]);
		t=0;
		for(int j=0;j<l;j++){
			//将字符型的数据用int型的num表示 
			if(isdigit(a[i][j])) num = a[i][j]-'0';
			else num = a[i][j]-'A'+10;
			//将num转化为四个二进制数 
			for(int z=3;z>=0;z--){
				b[j*4+z]=num%2;
				num/=2;
			}
			t+=4;//十六进制每转化一个数据就进行+4		
		}
		//tt用来表示转化为八进制的下标 
		int tt=0;
		//将三个二进制数转化为一个八进制数 
		for(int T=t-1;T>=0;T-=3){
			for(int j=0;j<3;j++)		
				if(b[T-j]) num+=pow(2,j);//num表示转化为八进制的数 
			c[tt++]=num+'0';
			num=0;
		}
		//将十六进制转化为四个二进制会出现后面三个均为0的 
		if(c[tt-1]!='0') cout<<c[tt-1];
		for(int j=tt-2;j>=0;j--)
			cout<<c[j];
		cout<<endl;
	}
	return 0;
}

最后,有不对的地方欢迎大家指正。有疑问的,可以评论或私信作者,本人尽力解答OvO

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值