蓝桥杯试题 基础练习 BASIC-12 十六进制转八进制 JAVA——冲刺蓝桥杯第六天

前言

进制转化包括这篇我写了三篇了,这篇没讲的好多要点都在其他两篇讲到了大家有需要请点击下面链接跳转去学习
有点累了,害,Keep Walking

蓝桥杯试题 基础练习 BASIC-11十六进制转十进制——冲刺蓝桥杯第六天
蓝桥杯试题 基础练习 BASIC-10十进制转十六进制——冲刺蓝桥杯第五天

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

资源限制
时间限制:1.0s 内存限制:512.0MB

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

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

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

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

样例输入
  2
  39
  123ABC

样例输出
  71
  4435274

【提示】
  先将十六进制数转换成某进制数,再由某进制数转换成八进制。

要点

  1. 仍然是数据范围
    在这里插入图片描述
    输入的16进制位数这么多,那肯定转化后的10进制数也很大啊,而且长度为100000的16进制数转化后的10进制数即使是long也放不下啊
    但是我们可以用String型,因为它容纳足够多的字符,我们将16进制字符串,转化为2进制字符串,再转化为8进制字符串
    16进制可以转化为4位2进制数,3位2进制数可以转化为1位8进制数
  2. 一定要注意题目给你的暗示
    在这里插入图片描述
    我们将16进制字符串,转化为2进制字符串,再转化为8进制字符串

思路一:简单方法——调用java自带的方法,发生了错误,这个方法本质上是16进制先转化为10进制,10进制再转化为8进制,但是因为输入的16进制的位数很多,导致转化后得到的10进制数很大,大到连long也放不下

Integer.toOctalString(Integer.valueOf(array[i], 16))
  1. Integer.valueOf(array[i], 16)
    Integer.valueOf(String s,in radix) (return)Integer
    该方法用来讲某字符串按某进制转化为Integer型,第一个参数为需要转化的字符串,第二个参数是转化采取的进制,返回类型为Integer
  2. Integer.toOctalString(int i) (return)String
    该方法将某int型整数转化为8进制字符串

本题代码

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        String[] array = new String[n];
        for (int i = 0; i < n; i++) {
            array[i] = scanner.next();
        }
        for (int i = 0; i < n; i++) {
            System.out.println(Integer.toOctalString(Integer.valueOf(array[i], 16)));
        }
        //我怀疑是这一步将字符串转化为Integer,而Integer放不下导致数据缺失
        // Integer.valueOf(array[i], 16)
    }
}

思路二:16进制先转化为2进制,2进制再转化为8进制

  1. 注意8进制是三个2进制数一组,所以对长度除以3取余数,不是3的整数倍的在前面补零
     //敲黑板。。。注意8进制是三个2进制数一组,所以对长度除以3取余数,不是3的整数倍的在前面补零
    if (strBinary.length() % 3 == 1) strBinary = "00" + strBinary;
    if (strBinary.length() % 3 == 2) strBinary = "0" + strBinary;
    
  2. 输入的十六进制数不会有前导0,比如012A。
    输出的八进制数也不能有前导0。
    在这里插入图片描述
    if (strBinary.substring(0, 3).equals("000")) {
    	//看看前三位是不是0,是零就从第四位开始截取,因为题目说输入的十六进制数不会有前导0,比如012A。
    	//所以最差的情况是输入的16进制数为"1",转化为2进制后为"0001",位数不是3的倍数,加0变为"000001"
    	//这种情况如果不处理,转化为8进制数就会变成"01"
    	//而题目要求输出的八进制数也不能有前导0。
    	//"000001"为最差情况,所以能处理它,别的就都能
    	k = 3;
    } else {
    	k = 0;
    }
    for (int i = k; i < strBinary.length() - 2; i += 3) {
    //省略}
    

本题代码

import java.util.Scanner;

public class Main{

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        String[] a = new String[n];
        for (int i = 0; i < n; i++) {
            a[i] = sc.next();//接受用户输入
        }
        sc.close();

        for (int i = 0; i < n; i++) {
            String strBinary = hexToBinary(a[i]);//16进制转化为2进制
            //敲黑板。。。注意8进制是三个2进制数一组,所以对长度除以3取余数,不是3的整数倍的在前面补零
            if (strBinary.length() % 3 == 1) strBinary = "00" + strBinary;
            if (strBinary.length() % 3 == 2) strBinary = "0" + strBinary;

            String strOctal = binaryToOctal(strBinary); //2进制转化为8进制
            System.out.println(strOctal);
        }
    }

    //十六进制转二进制算法
    private static String hexToBinary(String strHex) {
        StringBuilder sBuffer = new StringBuilder();
        for (int i = 0; i < strHex.length(); i++) {
            switch (strHex.charAt(i)) {//截取16进制数的每一个字符,并将其转换为对应2进制数
                case '0':
                    sBuffer.append("0000");
                    break;
                case '1':
                    sBuffer.append("0001");
                    break;
                case '2':
                    sBuffer.append("0010");
                    break;
                case '3':
                    sBuffer.append("0011");
                    break;
                case '4':
                    sBuffer.append("0100");
                    break;
                case '5':
                    sBuffer.append("0101");
                    break;
                case '6':
                    sBuffer.append("0110");
                    break;
                case '7':
                    sBuffer.append("0111");
                    break;
                case '8':
                    sBuffer.append("1000");
                    break;
                case '9':
                    sBuffer.append("1001");
                    break;
                case 'A':
                    sBuffer.append("1010");
                    break;
                case 'B':
                    sBuffer.append("1011");
                    break;
                case 'C':
                    sBuffer.append("1100");
                    break;
                case 'D':
                    sBuffer.append("1101");
                    break;
                case 'E':
                    sBuffer.append("1110");
                    break;
                case 'F':
                    sBuffer.append("1111");
            }
        }
        return sBuffer.toString();
    }

    //二进制转换为八进制算法
    private static String binaryToOctal(String strBinary) {
        int k;
        StringBuilder sBuffer = new StringBuilder();
        if (strBinary.substring(0, 3).equals("000")) {
            //看看前三位是不是0,是零就从第四位开始截取,因为题目说输入的十六进制数不会有前导0,比如012A。
            //所以最差的情况是输入的16进制数为"1",转化为2进制后为"0001",位数不是3的倍数,加0变为"000001"
            //这种情况如果不处理,转化为8进制数就会变成"01"
            //而题目要求输出的八进制数也不能有前导0。
            //"000001"为最差情况,所以能处理它,别的就都能
            k = 3;
        } else {
            k = 0;
        }

        for (int i = k; i < strBinary.length() - 2; i += 3) {
            if ("000".equals(strBinary.substring(i, i + 3))) {
                sBuffer.append("0");
            } else if ("001".equals(strBinary.substring(i, i + 3))) {
                sBuffer.append("1");
            } else if ("010".equals(strBinary.substring(i, i + 3))) {
                sBuffer.append("2");
            } else if ("011".equals(strBinary.substring(i, i + 3))) {
                sBuffer.append("3");
            } else if ("100".equals(strBinary.substring(i, i + 3))) {
                sBuffer.append("4");
            } else if ("101".equals(strBinary.substring(i, i + 3))) {
                sBuffer.append("5");
            } else if ("110".equals(strBinary.substring(i, i + 3))) {
                sBuffer.append("6");
            } else if ("111".equals(strBinary.substring(i, i + 3))) {
                sBuffer.append("7");
            }
        }
        return sBuffer.toString();

        //switch能判断字符串是在java1.7才有,一般蓝桥杯环境应该是1.6
        /*for (int i = k; i < strBinary.length() - 2; i += 3) {
            switch (strBinary.substring(i, i + 3)) {
                case "000":
                    sBuffer.append("0");
                    break;
                case "001":
                    sBuffer.append("1");
                    break;
                case "010":
                    sBuffer.append("2");
                    break;
                case "011":
                    sBuffer.append("3");
                    break;
                case "100":
                    sBuffer.append("4");
                    break;
                case "101":
                    sBuffer.append("5");
                    break;
                case "110":
                    sBuffer.append("6");
                    break;
                case "111":
                    sBuffer.append("7");
            }
        }
        return sBuffer.toString();*/
    }
}
爱做梦的鱼 CSDN认证博客专家 Java 大数据开发 CSDN签约作者
微信公众号【程序猿干货铺】,里面有各种学习资料和各种面试、笔试经验。东北大学大数据实验班大三学生,秋招求职中,斩获腾讯、华为、京东、美团等多家offer。我好菜啊,菜得我难过!
相关推荐
©️2020 CSDN 皮肤主题: 博客之星2020 设计师:CY__ 返回首页
实付 39.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值