先看原题
算法思路
Java 自带了转成十六进制、八进制、二进制的api。
每3个十六进制数由4个八进制数表示,所以需要将输入的十六进制数每3个拿出来转换一次,考虑到它可能不是3的倍数,可以事先再它前面补上若干个0,但考虑到长字符串(短的倒无所谓)String赋值、连接较慢,这里就不补0,而把高位余下的单独拿出来处理。
Integer java.lang.Integer.valueOf(String s, int radix)
这个方法可以将字符串以指定的进制读取,进制由radix指定,然后返回其十进制表示。
比如,Integer.valueOf("FF",16)
返回 255
String java.lang.Integer.toOctalString(int i)
这个方法则可以将一个十进制表示的数转化成其八进制表示,当然也有转成十六进制的方法。上下两个方法连用可以将一个十六进制的字符串转成其八进制字符串
Integer.toOctalString(Integer.valueOf(t,16))
值的注意的是,返回的字符串不带前缀0,也就是说如果3个十六进制转成2个八进制数,它不会自动在前面补两个0。所以要记得手动去补这两个0。
每次转换得到的短字符串都append到一个StringBuilder中,为什么不用String呢?String会慢很多,慢到无法通过本题的时间限制,具体原因可以去百度下。
算法代码
import java.lang.reflect.Array;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int begin = 0,end = 2,step = 3;
String temp;
for(int i=0;i<n;i++) {
StringBuilder octResult = new StringBuilder("");
begin = 0;end = 2;
temp = in.next();
// long time = System.currentTimeMillis();
// 判断是否位数是否为3的倍数, 决定在前面补多少个零
int stringLength = temp.length();
int dividedResult = stringLength%3;
if(dividedResult == 1) {
String t = temp.substring(0,1);
t = "00"+t;
octResult.append(Integer.toOctalString(Integer.valueOf(t,16)));
begin = 1;
end = 3;
}else if(dividedResult == 2) {
String t = temp.substring(0,2);
t = "0"+t;
octResult.append(Integer.toOctalString(Integer.valueOf(t,16)));
begin = 2;
end = 4;
}
// System.out.println(System.currentTimeMillis()-time);
// 然后从左往右每3位处理一次
while(end<=stringLength-1) {
String t = Integer.toOctalString(Integer.valueOf(temp.substring(begin,end+1),16));
if(t.length()==1) {
t = "000"+t;
}else if(t.length()==2) {
t = "00"+t;
}else if(t.length()==3) {
t = "0"+t;
}
octResult.append(t);
begin += step;
end += step;
}
System.out.println(octResult);
octResult = null;
// System.out.println(System.currentTimeMillis()-time);
}
in.close();
}
}