问题描述:
给定n个十六进制正整数,输出它们对应的八进制数。
资源限制:
时间限制:1.0s 内存限制:512.0MB
输入格式:
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由09、大写字母AF组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式:
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入:
2
39
123ABC
样例输出:
71
4435274
【提示】
先将十六进制数转换成某进制数,再由某进制数转换成八进制。
分析:
一看这题,以为就是把16进制转换成十进制再转换成八进制,还给了个提示,我寻思着这谁想不到呀,就开始写了,写完之后发现,嗯?
这测试数据就离谱。我也意识到同类型最大的十六进制远比同类型最大的十进制要大得多,所以转化到十进制的时候必会溢出。于是我又去康了康别人写的怎么样。恍然大悟,可以用字符串来表示二进制一组一组的进行转化。先通过8421法转化成二进制再用421法转化为八进制。于是就有了下面的代码
import java.util.Scanner;
public class er {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
int ass=in.nextInt();
String[] r=new String[ass];
for (int i=0;i<ass;i++){
r[i]=in.next();
}
for (int i=0;i<ass;i++){
System.out.println(too(tob(r[i])));
}
}
public static String tob(String ass) {
String r="";
for(int i=ass.length()-1;i>=0;i--) {
String t=ass.substring(i,i+1);
String num=Integer.toBinaryString(Integer.parseInt(t, 16));
if (num.length()<4){ //如果二进制不足四位向前补0
for (int w=4-num.length();w>0;w--){
num="0"+num;
}
}
r=num+r;
}
return r;
}
public static String too(String ass){
String r="";
if (ass.length()%3!=0){
for (int i=3-(ass.length()%3);i>0;i--){ //不是三的倍数在前面补0
ass="0"+ass;
}
}
//取三位进行421法转8进制
for (int i=0;i<ass.length();i=i+3){
String num=ass.substring(i,i+3);
int p=0;
for (int s=0;s<num.length();s++){
p=Integer.parseInt(num.substring(s,s+1))*(int)Math.pow(2,2-s)+p;
}
num= String.valueOf(p);
r=r+num;
}
r=r.replaceFirst("^0*","");
return r;
}
}
测试了一下好像完全符合要求,结果。。。
我是sb