十六进制转八进制
1 题目
题目:十六进制转八进制
问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由09、大写字母AF组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
2 解题过程
2.1 第一版代码
偷懒直接使用java的转换函数写出了第一个版本,尝试提交。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
scanner.nextLine(); // 获取nextInt之后的一个一个换行符
for (int i = 0; i < n; i++) {
// 直接使用Integer里面封装好的转换函数
// 先16进制转为10进制,再10进制转8进制
System.out.println(Integer.toOctalString(Integer.parseInt(scanner.nextLine(), 16)));
}
scanner.close();
}
}
自己测试了一下是没有问题的。但是提交上去直接显示运行错误了,下载输入数据看了下,
数据的确很大,毕竟题目也说16进制数在十万位以内。(但是第一行为啥n的数据没有换行呢?是不是txt文档的问题?)估计就是数据太长的原因,因为用java的函数期间把16进制转换为了10进制的int类型,10万位的16进制转换位10进制绝对不是int类型能容纳的下的。看来16转8就是比另外两个16转10,10转16要麻烦。
2.2 StringBuffer、StringBuilder、String
再去参考了一下别人的代码,还是得用字符串存储的方式。然后自己用String写了一下发现不行,就了解了一下StringBuffer、StringBuilder、String的区别。以前虽然知道C#中的String也是不可改变的,每次修改都是创建一个新的String。然而Java中String在创建之后是完全不能修改的。这就引出了可以修改的StringBuffer和StringBuilder。他们三个的区别大概如下。
- String,创建之后不可修改。
- StringBuffer,可修改,线程安全,速度较StringBuilder慢。
- StringBuilder,可修改,线程不安全,速度较StringBuffer快。
现在的情况需要创建一个不停修改的字符串用StringBuilder就好的。
2.3 将16进制转为2进制的字符串
其实直接判断读取进来的字符,写好16进制和2进制的转换关系,把2进制的字符串接起来。
String hexNum = scanner.nextLine();
StringBuilder binaryNum = new StringBuilder();
for (int j = 0;j < hexNum.length(); j++) {
switch (hexNum.charAt(j)) {
case '0':binaryNum.append("0000");break;
case '1':binaryNum.append("0001");break;
case '2':binaryNum.append("0010");break;
case '3':binaryNum.append("0011");break;
case '4':binaryNum.append("0100");break;
case '5':binaryNum.append("0101");break;
case '6':binaryNum.append("0110");break;
case '7':binaryNum.append("0111");break;
case '8':binaryNum.append("1000");break;
case '9':binaryNum.append("1001");break;
case 'A':binaryNum.append("1010");break;
case 'B':binaryNum.append("1011");break;
case 'C':binaryNum.append("1100");break;
case 'D':binaryNum.append("1101");break;
case 'E':binaryNum.append("1110");break;
case 'F':binaryNum.append("1111");break;
default:break;
}
}
2.4 将2进制的字符串转换为8进制
// 确保二进制字符串是3的倍数
while(binaryNum.length() % 3 != 0) {
binaryNum.insert(0, '0'); // 当长度对3求余不等于0的时候在前面加一个0
}
// 转换为8进制
StringBuilder octNum = new StringBuilder();
for (int j = 0; j < binaryNum.length(); j += 3) {
String temp = binaryNum.substring(j, j+3);
switch (temp) {
// 每三个字符作为一个子串,进行判断和添加
case "000": octNum.append("0"); break;
case "001": octNum.append("1"); break;
case "010": octNum.append("2"); break;
case "011": octNum.append("3"); break;
case "100": octNum.append("4"); break;
case "101": octNum.append("5"); break;
case "110": octNum.append("6"); break;
case "111": octNum.append("7"); break;
default: break;
}
}
// 消除前导0
while(octNum.charAt(0) == '0') {
octNum.deleteCharAt(0); // 当第一个数是0的时候删除第一数
}
2.5 完整代码
终于运行成功了。531ms,42.92MB。感觉好高啊,感觉随时会超时。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
scanner.nextLine();
for (int i = 0; i < n; i++) {
String hexNum = scanner.nextLine();
StringBuilder binaryNum = new StringBuilder();
for (int j = 0;j < hexNum.length(); j++) {
switch (hexNum.charAt(j)) {
case '0':binaryNum.append("0000");break;
case '1':binaryNum.append("0001");break;
case '2':binaryNum.append("0010");break;
case '3':binaryNum.append("0011");break;
case '4':binaryNum.append("0100");break;
case '5':binaryNum.append("0101");break;
case '6':binaryNum.append("0110");break;
case '7':binaryNum.append("0111");break;
case '8':binaryNum.append("1000");break;
case '9':binaryNum.append("1001");break;
case 'A':binaryNum.append("1010");break;
case 'B':binaryNum.append("1011");break;
case 'C':binaryNum.append("1100");break;
case 'D':binaryNum.append("1101");break;
case 'E':binaryNum.append("1110");break;
case 'F':binaryNum.append("1111");break;
default:break;
}
}
while(binaryNum.length() % 3 != 0) {
binaryNum.insert(0, '0');
}
StringBuilder octNum = new StringBuilder();
for (int j = 0;j < binaryNum.length();j+=3) {
String temp = binaryNum.substring(j, j+3);
switch (temp) {
case "000": octNum.append("0"); break;
case "001": octNum.append("1"); break;
case "010": octNum.append("2"); break;
case "011": octNum.append("3"); break;
case "100": octNum.append("4"); break;
case "101": octNum.append("5"); break;
case "110": octNum.append("6"); break;
case "111": octNum.append("7"); break;
default: break;
}
}
while(octNum.charAt(0) == '0') {
octNum.deleteCharAt(0);
}
System.out.println(octNum);
}
scanner.close();
}
}