1.题目
问题描述 给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由09、大写字母AF组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式: 输出n行,每行为输入对应的八进制正整数。
【注意】 输入的十六进制数不会有前导0,比如012A。 输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
【提示】
先将十六进制数转换成某进制数,再由某进制数转换成八进制。
2.思路
- 自己的思路:看了题目提示“先将十六进制数转换成某进制数,再由某进制数转换成八进制。”想的就是先将十六进制转成十进制,再将十进制转成八进制,自己写了一遍。但是提交过后却是错误零分。
内联代码片
。
public class HexToOctal {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();
ArrayList<String> s = new ArrayList<String>();
for(int i = 0; i < 2 * m - 1; i++) {
String a = sc.nextLine();
if(a.length() == 0) {
continue;
}else
s.add(a);
}
convertToDeciamalAndOctal(s);
}
public static void convertToDeciamalAndOctal(ArrayList<String> s) {
int[] arr = new int[s.size()];
for(int i = 0; i < s.size(); ++i) {
arr[i] = Integer.parseInt(s.get(i), 16);
}
for (int i = 0; i < arr.length; i++) {
System.out.println(Integer.toOctalString(arr[i]));
}
}
}
- 后面参考了其他博主的文章,意识到了自己的错误是“每个十六进制数长度不超过100000。”稍微大一点的十六进制连long都无法表示了。此时思路就是将十六进制先转成二进制,再用二进制转成八进制,并且都以字符串存储,这样避免无法存储的情况。
难点体会及注意事项:
(1)注意从键盘获取数据时, sc.nextLine(); 和 sc.next() 的区别,最好是采用后者,因为我发现用 sc.nextLine()时会将换行符也读入,导致后面还需单独处理,而 sc.next()就能屏蔽换行符之类的带来的影响。
(2)不断追加字符串时最好使用StringBuffer或者StringBuilder,但是这样用String接收返回的StringBuffer或者StringBuilder时候就要注意调用toString方法,当时没自己写的时候看博主的,还认为toString可有可无。
(3)StringBuffer线程不安全但速度快,StringBuilder线程安全相对StringBuilder就会慢一点点
(4)内联代码片
。
import java.util.Scanner;
public class HexToOctal_2 {
//创建全局变量
static String[] bin = {"0000","0001","0010","0011","0100","0101","0110","0111",
"1000","1001","1010","1011","1100","1101","1110","1111"};
static String[] oct = {"0","1","2","3","4","5","6","7"};
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();
String[] a = new String[m];
for(int i = 0; i < m; ++i) {
a[i] = sc.next();
}
for(int i = 0; i < m; ++i) {
/*
* hexToBin(a[i]).toString() 十六进制转二进制
* binToOct(hexToBin(a[i]).toString()).toString() 二进制转八进制
*/
String res1 = binToOct(hexToBin(a[i]).toString()).toString();
if(res1.startsWith("0") ) {
System.out.println(res1.substring(1));
} else
System.out.println(res1);
}
}
//十六进制转二进制(取出数值)
public static StringBuilder hexToBin(String s) {
StringBuilder sb = new StringBuilder();
int start = 0;
int end = 1;//一位16进制数转化成思位二进制数,即 1,2,4,8
while(end <= s.length()) {
String str = transformToBin(s.substring(start, end));
start += 1;
end += 1;
sb.append(str);
}
return sb;
}
//十六进制转二进制(将取出的数字转化成二进制)
public static String transformToBin(String s) {
String b = null;
switch(s) {
case "0": b = bin[0]; break;
case "1": b = bin[1]; break;
case "2": b = bin[2]; break;
case "3": b = bin[3]; break;
case "4": b = bin[4]; break;
case "5": b = bin[5]; break;
case "6": b = bin[6]; break;
case "7": b = bin[7]; break;
case "8": b = bin[8]; break;
case "9": b = bin[9]; break;
case "A": b = bin[10]; break;
case "B": b = bin[11]; break;
case "C": b = bin[12]; break;
case "D": b = bin[13]; break;
case "E": b = bin[14]; break;
case "F": b = bin[15]; break;
}
return b;
}
//二进制转八进制(取出三个二进制)1 2 4 = 7
public static StringBuilder binToOct(String s) {
StringBuilder sb = new StringBuilder();
int start = 0;
int end = 3;
if(s.length() % 3 == 1) {
s = "00" + s;
}
if(s.length() % 3 == 2) {
s = "0" + s;
}
while(end <= s.length()) {
String str = transformToOct(s.substring(start, end));
start += 3;
end += 3;
sb.append(str);
}
return sb;
}
public static String transformToOct(String s) {
String b = new String();
switch(s) {
case "000": b = oct[0]; break;
case "001": b = oct[1]; break;
case "010": b = oct[2]; break;
case "011": b = oct[3]; break;
case "100": b = oct[4]; break;
case "101": b = oct[5]; break;
case "110": b = oct[6]; break;
case "111": b = oct[7]; break;
}
return b;
}
}
- 上面的方法写出来之后感觉还是有点复杂,一百来行代码呢,然后我就继续找啊找,主要也不太看得懂c++的方法,找呀找还真逛到了更简单的方法,然后迫不及待的提交去测试,啪,满分通过,神了。API真神奇居然还有BigInteger这东西。
下面展示一些 内联代码片
。
import java.math.BigInteger;
import java.util.Scanner;
public class HexToOctal_3 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();
String[] a = new String[m];
for(int i = 0; i < m; ++i) {
a[i] = sc.next();
}
for(int i = 0; i < m; ++i) {
System.out.println(new BigInteger(a[i],16).toString(8));
}
}
}
我的理解:
-
BigInteger(a[i],16),16是告诉编译器a[i]是一个十六进制的String类型的数,然后让它转化成十进制。
API:
-
toString(8)),将十进制数转化成八进制数。
API:
只能感叹API的伟大了。。。。
参考文章:
1.链接: link.
2.链接: link.
学习心得:神了。又是秃头的一天