蓝桥杯基础练习试题:十六进制转八进制 (Java 实现)

试题 基础练习 十六进制转八进制

问题描述
  给定 n 个十六进制正整数,输出它们对应的八进制数。

输入格式
  输入的第一行为一个正整数 n (1<=n<=10)。
  接下来 n 行,每行一个由 0~9、大写字母 A~F 组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过 100000。

输出格式
  输出 n 行,每行为输入对应的八进制正整数。

  【注意】
  输入的十六进制数不会有前导 0,比如 012A。
  输出的八进制数也不能有前导 0。

这道题目的第一个注意点是,蓝桥杯是一次性输入数据,所以用一个 Scanner 获取一次数据就够了,用多个会出现运行错误;
第二个注意点是,结果不能有前导 0

解题思路,根据提示【先将十六进制数转换成某进制数,再由某进制数转换成八进制】,我们可以使用平时进制转换的做法,先把十六进制转换为二进制,然后再从二进制转换为八进制。

为什么不转换为十进制?因为蓝桥杯的测试数据非常大,转换后的十进制数连 long 类型都装不下。

按照我们平时进制转换的做法是这样

假设有十六进制数 2E5A0

先转为二进制数

每一位十六进制数可以用4位二进制数来表示

0010 1110 0101 1010 0000

接着将二进制数转为八进制数

每一位八进制数可以用3位二进制数来表示
也就是说每3位二进制数代表一位八进制数

00 101 110 010 110 100 000

将前导0去除后转八进制

562640

这样就得到了一个八进制数了

所以我们代码也是用这种方法,简单,容易理解

我们要将十六进制和八进制与对应的二进制数进行,所以可以定义好这些数二进制数,在后面转换时直接拿来使用
因为下面要判断三位二进制数对应的八进制是多少,我采用获取下标的方式来获取对应八进制数,所以将八进制对应的二进制数数组存到 Array 里面,下面直接调用方法来获取下标

String[] hexBt = new String[]{ "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
String[] octBt = new String[]{"000", "001", "010", "011", "100", "101", "110", "111"};
ArrayList<String> octBtArray = new ArrayList<>(Arrays.asList(octBt));

首先获取输入数据,把第一行的 n 给拿出来,然后再把下面每一行的十六进制数存起来

Scanner scanner = new Scanner(System.in);
int n = Integer.parseInt(scanner.nextLine());
String[] hex = new String[n];
for(int i = 0;i<n;i++){
    hex[i] = scanner.nextLine();
}
scanner.close();

我们可以写一个 for 循环来遍历所有数据,进行转换输出,在循环里面写我们的算法

首先我们需要存下转换的二进制数和八进制数,由于是一位一位数进行转换,所以我们需要可变字符串来存储

由于用每 3 位数二进制数代表一个八进制数,也就是说我们每次取值都需要取 3 位数,所以要判断转换后的二进制数是否为 3 的倍数,如果不是需要在前面补上 0

for (int i = 0; i < n; i++) {
    // 存二进制数
    StringBuilder octTransform = new StringBuilder();
    // 存八进制数
    StringBuilder octBuilder = new StringBuilder();

    // 将每位十六进制数转换为二进制数
    for (int ii = 0; ii<hex[i].length(); ii++){
        String a = hex[i].substring(ii,ii+1);   // 获取一位十六进制数
        int ten = Integer.parseInt(a, 16);  // 十六进制数转为十进制数作为下标
        octTransform.append(hexBt[ten]);    // 存入对应下标的二进制数
    }

    // 补0至长度为3的倍数
    for(int ii = 3-octTransform.length()%3;ii>0&&i!=3;ii--){
        octTransform.insert(0, "0");
    }

    // 每次取三位数字进行转换
    for(int ii = 0; ii!=octTransform.length(); ii=ii+3){
        int index = octBtArray.indexOf(octTransform.substring(ii, ii+3));   // 判断取到的3位数在octBt数组的位置
        octBuilder.append(index);   // 存入对应8进制数
    }

    // 去除前导0
    if(octBuilder.charAt(0)=='0'){
        octBuilder = octBuilder.deleteCharAt(0);
    }

    // 根据蓝桥杯要求输出结果
    System.out.println(octBuilder.toString());
}

这样我们就完成了整个算法了,下面是我的提交结果

代码长度       语言    评测结果     得分    CPU使用     内存使用
1.598KB       JAVA     正确       100     265ms      45.66MB

完整的代码如下,记得类名必须是 Main

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {

        String[] hexBt = new String[]{ "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
        String[] octBt = new String[]{"000", "001", "010", "011", "100", "101", "110", "111"};
        ArrayList<String> octBtArray = new ArrayList<>(Arrays.asList(octBt));

        Scanner scanner = new Scanner(System.in);
        int n = Integer.parseInt(scanner.nextLine());
        String[] hex = new String[n];

        for(int i = 0;i<n;i++){
            hex[i] = scanner.nextLine();
        }
        scanner.close();

        for (int i = 0; i < n; i++) {

            StringBuilder octTransform = new StringBuilder();
            StringBuilder octBuilder = new StringBuilder();

            for (int ii = 0; ii<hex[i].length(); ii++){
                String a = hex[i].substring(ii,ii+1);
                int ten = Integer.parseInt(a, 16);
                octTransform.append(hexBt[ten]);
            }

            for(int ii = 3-octTransform.length()%3;ii>0&&i!=3;ii--){
                octTransform.insert(0, "0");
            }

            for(int ii = 0; ii!=octTransform.length(); ii=ii+3){
                int index = octBtArray.indexOf(octTransform.substring(ii, ii+3));
                octBuilder.append(index);
            }

            if(octBuilder.charAt(0)=='0'){
                octBuilder = octBuilder.deleteCharAt(0);
            }

            System.out.println(octBuilder.toString());
        }
    }
}