前言

传送门
起初想先将16进制转为10进制再转为8进制,发现题目中16进制数长度可达100000,即使是long long类型,范围也没那么大,于是准备将16进制转为2进制,再将2进制转为8进制。
16进制转2进制,就每一位16进制数转为4位2进制数即可,用一个string变量存储转换后的2进制数,再对这个string变量,每三位做一组,转换为一位8进制数即可,值得注意的是题目要求输出的8进制不能有前导0,因此需要判断一下,如果前导为0,就不要输出前导0了

正文

问题描述

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

输入格式

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

输出格式

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

【注意】

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

样例输入

2
39
123ABC

样例输出

71
4435274

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

AC代码

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream> 
using namespace std;
//16进制转8进制
void convert(){
	string str,str2,res;
	cin>>str;
	int len=str.length(),x;
	//16进制转为2进制 ,存储到str2中 
	for(int i=0;i<len;i++){
		switch(str[i]){
			case '0':str2 += "0000"; break;  
            case '1':str2 += "0001"; break;  
            case '2':str2 += "0010"; break;  
            case '3':str2 += "0011"; break;  
            case '4':str2 += "0100"; break;  
            case '5':str2 += "0101"; break;  
            case '6':str2 += "0110"; break;   
            case '7':str2 += "0111"; break;  
            case '8':str2 += "1000"; break;  
            case '9':str2 += "1001"; break;  
            case 'A':str2 += "1010"; break;  
            case 'B':str2 += "1011"; break;  
            case 'C':str2 += "1100"; break;  
            case 'D':str2 += "1101"; break;  
            case 'E':str2 += "1110"; break;  
            case 'F':str2 += "1111"; break; 
		}
	}
	//除以3后的余数 ,x表示次方 ,8进制由三位二进制表示,三位的权重分别为 2^2,2^1,2^0;
	int remain=str2.length()%3;
	if(remain==0) x=2;
	else if(remain==1)x=0;
	else if(remain==2)x=1;
	
	int tempNum=0;
	//二进制转8进制,注意题目要求输出的8进制不能有前导0 
	bool isZero=false; 
	for(int i=0;i<str2.length();i++){
		tempNum+=(str2[i]-'0')*pow(2,x);//字符转数字 
		x--;
		if(x==-1){
			x=2;
			//前导为0,此时continue跳过本次循环,去除前导0 
			if(isZero==false&&tempNum==0){
				tempNum=0;
				isZero=true;
				continue; 
			}
			//前导不为0,后面就不用判断了,故设置isZero为真 
			if(isZero==false)isZero=true;
			res+=(tempNum+'0');//数字转字符串 
			tempNum=0; 
		}
	} 
	cout<<res<<endl;
}

int main(){
	int n;
	scanf("%d",&n);
	while(n--){
		convert();	
	}
	return 0;
}

后记

经历27天的域名备案终于好了,真不知踩了多少坑,下面是结合GitHub上一个开源的视频播放器做的一个小demo——>https://www.inzc.top/nzc/finalWork/test/