蓝桥杯题目——十六进制转八进制
先展示两种很容易想到的思路
第一种:他们之间的转换可以先转成二进制然后再相互转换。
第二种:他们之间的转换可以先转成十进制然后再相互转换。
开始省题没省清楚,直接写了一段代码,用的是第二种思路,测试不通过,下载了用例输入之后才发现,六进制数的位数很长,无法用int或者long来保存结果。用例输入:
原始代码
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class Main {
static Map<Character,Integer> map = new HashMap<Character,Integer>();
static Scanner scanner = new Scanner(System.in);
static void init() {
map.put('0', 0);
map.put('1', 1);
map.put('2', 2);
map.put('3', 3);
map.put('4', 4);
map.put('5', 5);
map.put('6', 6);
map.put('7', 7);
map.put('8', 8);
map.put('9', 9);
map.put('A', 10);
map.put('B', 11);
map.put('C', 12);
map.put('D', 13);
map.put('E', 14);
map.put('F', 15);
}
static void smallexchange(int n){
int res=0;
String str = null;
Character c = null;
for (int i = 0; i < n; i++) {
res = 0;
str = scanner.next();
// 十六进制转十进制
for (int j = 0; j < str.length(); j++) {
c = str.charAt(str.length()-j-1);
res += map.get(c) * Math.pow(16,j);
}
// 十进制转8进制
System.out.println(Integer.toOctalString(res));
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
init();
int n;
n = scanner.nextInt();
smallexchange(n);
}
}
然后我就换了一个思路,使用思路一。具体实现如下。
十六进制转二进制
十六进制中一个字符的范围是0~15,对应了四位二进制,通过将读入的每一个字符都转化为四位二进制码保存在数组中,之后再将二进制转化为八进制。
需要注意,这里使用了integer类中的方法来将一位数字转化为二进制数,但是我们要求的数是一个整体,单个求则将前面0位吞掉了,会导致结果的错误。如图
static void bigexchange(int n) {
String str = null;
Character c = null;
String strres = null;
int count;
ArrayList<Integer> arr = new ArrayList<Integer>();
ArrayList<Integer> arrres = new ArrayList<Integer>();
for (int i = 0; i < n; i++) {
arr.clear();//重新计算十六进制数
str = scanner.next();
// 十六进制转二进制
for (int j = 0; j < str.length(); j++) {
c = str.charAt(j);
strres = Integer.toBinaryString(map.get(c));
// 除首位,其余位需要补齐四位
count = 4 - strres.length();
while (count!=0 && j!=0) {
arr.add(0);
count--;
}
for(int s = 0; s < strres.length(); s++) {
//将字符转化为对应的数字储存在数组中0的ASCII码值为48
arr.add((int) strres.charAt(s)-48);
}
}
System.out.print("十六进制转二进制输出"+arr);
// 二进制转八进制
// 对八进制数的首个元素先做处理,使列表里的数是3的倍数
switch (arr.size()%3) {
case 1:
arrres.add(arr.get(0));
arr.remove(0);
break;
case 2:
arrres.add(arr.get(0)*2 + arr.get(1));
arr.remove(0);
arr.remove(1);
break;
default:
break;
}
// 列表的数三个为一组,计算出八进制数
for(int k = 0; k < arr.size()/3; k++) {
arrres.add(arr.get(k*3)*4 + arr.get(k*3+1)*2 + arr.get(k*3+2));
}
for (int item : arrres) {
System.out.print(item);
}
}
}
代码的输出如下:输入要转化的数字个数和数字,输出对应的二进制
二进制转八进制
同理,三位二进制数对应一位八进制数,我们需要从列表尾部开始,每次取三个数字,将其转化为一位八进制数存储起来即可。
但考虑到序列不一定是三的整数倍,且从后遍历输出时需要逆输出,我们先计算出八进制数的第一位,即对列表取余,前余数位计算出八进制数第一位,然后将起从序列中删去,这样我们就可以正向从头开始对序列循环取三位求数了。
static void bigexchange(int n) {
String str = null;
Character c = null;
String strres = null;
ArrayList<Integer> arr = new ArrayList<Integer>();
ArrayList<Integer> arrres = new ArrayList<Integer>();
for (int i = 0; i < n; i++) {
arrres.clear();
arr.clear();//重新计算十六进制数
str = scanner.next();
// 十六进制转二进制
for (int j = 0; j < str.length(); j++) {
c = str.charAt(j);
strres = Integer.toBinaryString(map.get(c));
for(int s = 0; s < strres.length(); s++) {
//将字符转化为对应的数字储存在数组中0的ASCII码值为48
arr.add((int) strres.charAt(s)-48);
}
}
System.out.print("十六进制转二进制输出"+arr);
// 二进制转八进制
// 对八进制数的首个元素先做处理,使列表里的数是3的倍数
switch (arr.size()%3) {
case 1:
arrres.add(arr.get(0));
arr.remove(0);
break;
case 2:
arrres.add(arr.get(0)*2 + arr.get(1));
arr.remove(0);
arr.remove(1);
break;
default:
break;
}
// 列表的数三个为一组,计算出八进制数
for(int k = 0; k < arr.size()/3; k++) {
arrres.add(arr.get(k*3)*4 + arr.get(k*3+1)*2 + arr.get(k*3+2));
}
System.out.print("二进制转八进制输出"+arrres);
}
}
然后只需对输出稍作调整即可。