问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
【提示】
先将十六进制数转换成某进制数,再由某进制数转换成八进制。
求解:
NO.1
看了题目感觉so easy呀,16进制转10进制,10进制再转8进制就完美解决了。于是,代码如下:
import java.util.Scanner;
/**
* @author 作者 : Cactus
* @version 创建时间:2018-2-13 下午06:10:08
*/
public class Main {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
String[] nums = new String[n];
for(int i = 0;i < n;i++){
Integer x = Integer.parseInt(sc.next(), 16);
String o = Integer.toOctalString(x);
nums[i] = o;
}
for(int i = 0;i < n;i++){
System.out.println(nums[i]);
}
}
}
然鹅,测试结果是这样的:
为什么呢? 看到测试数据你就明白了,测试数据的冰山一角如下图:
NO.2
在网上查找了诸多大神的解决方法后,豁然开朗!
提示里的某进制就是2进制!!!
16进制数直接转2进制,怎么转?
学过计算机导论的同学应该知道,1位16进制数可以直接转换为4位2进制数,那么就可以依次将16进制数的每一位依次转换为4位2进制数然后拼接在一起。
同样的,3位2进制数可以直接转换为1位8进制数,于是我们就可以再把转化成功的2进制数再直接转成一个8进制数。(还有一些细节问题,具体看代码吧)
代码如下:
import java.util.Scanner;
/**
* @author 作者 : Cactus
* @version 创建时间:2018-2-13 下午06:10:08
*/
public class Main {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
String[] nums = new String[n];
for(int i = 0; i < n; i++){
//16进制 -> 2进制
StringBuilder sb1 = new StringBuilder();//字符串生成器,用于保存2进制数据
String s = sc.next();
for(int j =0; j < s.length(); j++){
char c = s.charAt(j);
String a = Integer.toBinaryString(Integer.valueOf(String.valueOf(c), 16));
for(int k = a.length(); k < 4; k++){
a = "0"+a;
}
sb1.append(a);
}
//2进制 -> 8进制
// 3位二进制表示1位8进制,故若二进制位数不为3的倍数,则需要补位
int l_remainder = 3 - sb1.toString().length()%3;
if(l_remainder != 3){
for(int m = 0; m < l_remainder; m++){
sb1 = new StringBuilder("0").append(sb1);
}
}
//转化
StringBuilder sb2 = new StringBuilder();
for(int o = 0; o < sb1.length(); o += 3){
// public String substring(int start,int end)
// 参数:
// start - 起始索引(包含)。
// end - 结束索引(不包含)。
String num = sb1.substring(o, o+3);
String sb2_part =Integer.toOctalString(Integer.valueOf(String.valueOf(num), 2));
sb2.append(sb2_part);
}
//正则表达式去前导零,正则表达式还得学习一波,有点懵逼!
// public String replaceAll(String regex,String replacement)
// 参数:
// regex - 用来匹配此字符串的正则表达式
// replacement - 用来替换每个匹配项的字符串
// 返回:
// 所得 String
nums[i] = sb2.toString().replaceAll("^(0+)", "");
}
for(int i = 0;i < n;i++){
System.out.println(nums[i]);
}
}
}
测试结果如下: