试题 基础练习 十六进制转八进制

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

思路: 先把16进制转换成二进制然后再把二进制转换成八进制。
一位16进制数需要4位二进制数表示,一位八进制数需要三位二进制表示。
所以这里我们先把16进制数转换成二进制然后每三个一组转换成八进制。
例如样例:
39(十六进制) 对应的2进制为 0011(3) 1001(9) 然后每三个一组输出分组如下(不足三个的补零) 00 111(7) 001(1) 对应的八进制为71(因为不能用前导0,所以0不输出)
在例如 123ABC 对应的二进制为(四位二进制数对应一个十六进制数)
0001 0010 0011 1010 1011 1100 然后每三个一组划分如下:
00(0)100(4) 100(4) 011(3) 101(5) 010(2) 111(7) 100(4) 故八进制数为443527

废话少说直接贴代码了

#include<bits/stdc++.h>

using namespace std;
const int MAXN=100001*4;
int a[MAXN]={0},b[MAXN];
char str[MAXN/4];
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		int f=4;//记录十六进制数转换成二进制数在数组中的位置 
        int ans=1;
		scanf("%s",str);
		int l=strlen(str);
		for(int i=l-1;i>=0;i--){
			if(str[i]>='A'&&str[i]<='F'){ 
				int temp=str[i]-'A'+10;//转换成数字 
				for(int j=f-4+1;j<=f;j++){//转换成二进制 
					a[j]=temp%2;
					temp/=2;
				}
				f+=4; //因为一个十六进制数转换为4为二进制数所以f+4 
			}
			else {
				int temp=str[i]-'0';
				for(int j=f-4+1;j<=f;j++){
					a[j]=temp%2;
					temp/=2;
				}
				f+=4;
			}
		}
		int e=1,count=0;
		f=f-4;//因为最后没有运算而且f+4了故应该减去这时候f就指向最后一位二进制了 
		while(e<=f){//转换成八进制 
			int sum=0,num=0,q=1;
			for(;e<=f;e++){
				num=num+a[e]*q;
				sum++;
				q*=2;
				if(sum==3) {
					e++;
					break;
				};
			}
			b[count++]=num;
		}
		while(b[count-1]==0){//防止有前导零 
			count--;
		}
		for(int i=count-1;i>=0;i--){
			printf("%d",b[i]);//输出八进制数 
		}
		printf("\n");
	}
	return 0;
}
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值