问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
【提示】
先将十六进制数转换成某进制数,再由某进制数转换成八进制。
import java.util.Scanner;
public class Faster {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner cin = new Scanner(System.in);
int n = cin.nextInt();
String s[] = new String[n];
for (int i = 0; i < n; i++) {
s[i] = cin.next();
// 解释一下为什么要用StringBuilder。
// StringBuilder 是可变长度的字符序列,而String是固定长度的
//String 每次相加,虽然长度变了,但是这是一个新的String实例
//所以,频繁的相加,会增加开销
//StringBuilder 可以随便增加
StringBuilder sBuilder = new StringBuilder();
for (int j = 0; j < s[i].length(); j++) {
char c = s[i].charAt(j);
String str = Integer.toBinaryString(Integer.valueOf(c+"",16));
for (int k = str.length(); k < 4; k++) {
str = '0'+str;
}
sBuilder.append(str);
}
//把二进制字符串的位数变为3的倍数,此处有一个问题。如果length()的长度正好等于3的倍数,此时needToAdd = 3
//相当于多加了3个零,那么在输出结果上就会出现前导0
// 123ABC这个测试用例就会出现前导0
//所以在后面要使用正则表达式,来控制输出
int needToAdd = 3-sBuilder.length()%3;
StringBuilder octal = new StringBuilder();
for (int j = 0; j < needToAdd; j++) {
//因为 这是StringBuilder ,所以不能用 +号直接连接。
//对我来说,我没有想到如何在StringBuilder 对象前面加字符串"0"。
//下面这条语句 让我明白了。
sBuilder = new StringBuilder("0").append(sBuilder);
}
//格式转化完成之后,开始计算。
for (int j = 0; j < sBuilder.length(); j+=3) {
//a = (sBuilder.charAt(j)-'0')*4+(sBuilder.charAt(j+1)-'0')*2+(sBuilder.charAt(j+2)-'0')*1;
String sub = sBuilder.substring(j, j+3);//左闭右开
String o = Integer.toOctalString(Integer.valueOf(sub,2));
octal.append(o);
}
String result = octal.toString().replaceAll("^(0+)", "");
System.out.println(result);
}
}
}