问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
【提示】
先将十六进制数转换成某进制数,再由某进制数转换成八进制。
本来以为很简单, 直接读入字符串,转换成十进制的int,再转换成八进制, 测试样例通过了, 提交后是错的, 仔细看题后发现题目里说每个十六进制数长度不超过100000, 这么长, long long也装不下啊.
那只能用字符串保存了, 每一位16进制数对应着4位二进制数, 每3位二进制数对应一位八进制数, 我就老老实实的先把每位十六进制数转换成4位二进制的字符串, 一个十六进制数处理完后, 再转换成八进制, 写完提交, 结果超时了.
再改进一下, 容易发现每3位十六进制数对应4位八进制数. 所以可以每次处理3位十六进制数,转换成十进制后直接转换成4位八进制数, 为了方便, 在十六进制数的前面补0, 保证其长度为3的倍数, 这样写完之后发现还是超时.
还有什么地方能改进呢, 一番寻找之后终于想起了StringBuilder, 因为字符串很长, 需要频繁修改, StringBuilder修改的速度更快. 将所有的String换成StringBuilder后, 终于成功了. 由此可见, StringBuilder果然比String快的多啊…
下面贴上java代码:
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int n=scanner.nextInt();
ArrayList<String> list=new ArrayList<String>();//用来保存要输出的字符串
for (int k = 0; k < n; k++) {
StringBuilder hexString=new StringBuilder();
hexString.append(scanner.next());
StringBuilder octString=new StringBuilder();
while (hexString.length()%3!=0) { //在输入的字符串前补0,确保长度是3的倍数
hexString.insert(0,"0");
}
for (int i = 0; i < hexString.length(); i=i+3) {
int d=0;
for (int j = 0; j < 3; j++) { //从十六进制转换成十进制
char c=hexString.charAt(i+j);
int num=0;
if (c>='0'&&c<='9') {
num=c-'0';
}else {
num=c-'A'+10;
}
d=d*16+num;
}
//从十进制转换成八进制
octString.append(String.valueOf(d/512)+String.valueOf(d%512/64)+String.valueOf(d%64/8)+String.valueOf(d%8));
}
int i=0;
while (octString.charAt(i)=='0') {//去掉开头的0
i++;
}
list.add(octString.substring(i));
}
for (String str:
list) {
System.out.println(str);
}
}
}