Basic12 基础练习 十六进制转八进制
题目如下
这道算法题在我刚开始练的时候算是一个小boos了,进制转换听起来就很烦,在日常工作中我至少暂时还没有遇到这样的需求,就算真有进制转换的需求,java自带的进制转换函数就够用了。而靠算法显然就没这么简单,题目上说不超过100000位那就意味着最后一个测试样例必然接近100000,所以还是老老实实写算法好了
那十六进制怎么好转八进制呢,其实有很多方法,但最好的就是先将十六进制转化成二进制,再由二进制转化成八进制的,这里面也没啥好说的,一步步写就行,要注意的就是十六进制转化成二进制是4位,而二进制转八进制时是每3位转一次,这里所谓注意一下即可,下面的代码也写了注释
import java.util.Scanner;
/**
* @Description: 基础练习 十六进制转八进制
* @ClassName: Basic12
* @author: fan.yang
* @date: 2020/07/08 10:24
*/
public class Basic12 {
//纯算法解法 java也有一些进制转化函数 但对于本例长达100000的字符串是用不了的
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
StringBuffer sb = new StringBuffer();
//十六进制数转为二进制数为4位 所以搞个数组存一下
int[] binarys = new int[4];
//这是存八进制那三位对应的2平方的值 方便转化
int[] binary = new int[3];
binary[0] = 4; binary[1] = 2; binary[2] = 1;
int n = scanner.nextInt();
for(int i = 0;i < n;i++){
String hexNum = scanner.next();
//把获取到的十六进制字符串放到数组里 方便循环操作
char[] array = hexNum.toCharArray();
for(int j = 0;j < array.length;j++){
//c语言当初就这么写 就是asc码相减
int num = array[j] - '0';
if(array[j] >= 'A' && array[j] <= 'F'){
num = array[j] - 'A' + 10;
}
//十六进制比如4位 空的也要补零 所以强制循环4次 而且我是从后往前填 所以不用倒一下了
//比如3按这个过程会先后得到1 1 0 0 ,然后实际是0 0 1 1
int cycle = 4;
while(cycle-- > 0){
binarys[cycle] = num % 2;
num /= 2;
}
//然后将获得的二进制数往StringBuffer加
while(cycle++ < 3){
sb.append(binarys[cycle]);
}
}
//进制转换是要从后面的数开始的 比如00111001 是要分成 00 111 001,这样第一组会少
//所以要保证总数是3的倍数,少的补0
if(sb.length() % 3 != 0){
int length = sb.length();
for(int j = 0;j < 3 - (length % 3);j++){
sb.insert(0 , 0);
}
}
//接下来就是将二进制转成八进制的过程
int num = 0;
for(int j = 0;j < sb.length();j++){
//可能我写的不太好懂 这里详细说下这个过程
//首先这个binary数组的意思上面已经说过,其实就是存了4(2的2次),2(2的1次),1(2的0次),因为八进制最多三位
//而sb.charAt(j) - '0'其实是为了将字符转成数字 比如'1' --》 1
//假设sb为101 会进行3次循环
//第一次 num = num + ('1' - '0') * binary[0] num = 0 + 1 * 4 所以第一次循环结束num = 4
//第二次 num = num + ('0' - '0') * binary[1] num = 4 + 0 * 2 所以第二次循环结束num = 4
//第三次 num = num + ('1' - '0') * binary[2] num = 4 + 1 * 1 所以第三次循环结束num = 5
//这就是将二进制101转成八进制5的过程
num += (sb.charAt(j) - '0') * binary[j % 3];
//因为是3个二进制数转1个八进制的 所以每转完一个八进制就把num初始化为0
if((j + 1) % 3 == 0){
//这是怕转的第一个八进制是0,题目说不要前导0的
if(num != 0 || j + 1 != 3){
System.out.print(num);
}
num = 0;
}
}
System.out.println();
sb = new StringBuffer();
}
}
}