蓝桥杯【十六进制转八进制】Java

资源限制

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

问题描述

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

输入格式

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

输出格式

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

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

样例输入

2
39
123ABC

样例输出

71
4435274

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

思路分析

题目要求很简单,就是进制转换,根据提示先将十六进制转换为某进制,这里的某进制显然不能是十进制,虽然十进制有和其他进制转换的函数,但是题目规定十六进制数在100000位以内,何况转换后的十进制,即使最大的long类型也仅能存储19位的整型数据,所以中间的转换进制类型只能使用字符串存取了,方便字符串操作的,我们可以考虑二进制。
①将十六进制字符串每个字符依次转换为对应的四位01字符串
②然后将转换后的二进制字符串前补上相应的’0’使其长度为3的倍数,方便每3位截取转换为对应的八进制
③之后将二进制字符串每三位为一组转换为对应的八进制
④去掉前导0,输出八进制字符串(这里只需要判断字符串第一位是否为0即可,题目说明十六进制无前导0,即转换后的二进制前最多3个‘0’(十六进制以1开头的情况——0001),二进制转八进制时前面最多补2个‘0’(除3余2的情况),相加最多5个‘0’转换为八进制前导仅1个‘0’)
【注】 存储相应进制字符串应使用StringBuilder,因为转换过程中要经过多次字符串拼接,此时StringBuilder相对于基本类型String的效率就相对明显了(本人亲测,使用String内存超限)

代码实现
import java.io.*;
import java.util.*;

public class Main {
    
    
	public static void main(String[] args) throws IOException {
    
    
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
		int n = Integer.parseInt(br.readLine());
		Map<Character, String> HtoB = new HashMap<Character, String>();// 用于存储十六进制对应的二进制
		Character[] key = {
    
     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
		String[] value = {
    
     "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010",
				"1011", "1100", "1101", "1110", "1111" };
		for (int i = 0; i < 16; i++) {
    
    
			HtoB.put(key[i], value[i]);// 存储十六进制对应的二进制,键为16进制,值为2进制
		}
		Map<String, String> BtoO = new HashMap<String, String>();// 用于存储二进制对应的八进制
		String[] k = {
    
     "000", "001", "010", "011", "100", "101", "110", "111" };
		String[] v = {
    
     "0", "1", "2", "3", "4", "5", "6", "7" };
		for (int i = 0; i < 8; i++) {
    
    
			BtoO.put(k[i], v[i]);// 存储二进制对应的八进制,键为2进制,值为8进制
		}
		for (int i = 0; i < n; ++i) {
    
    
			StringBuilder H = new StringBuilder(br.readLine()), // 输入十六进制字符串
					B = new StringBuilder(), // 初始二进制字符串
					O = new StringBuilder();// 初始八进制字符串
			for (int j = 0; j < H.length(); j++) {
    
    
				B.append(HtoB.get(H.charAt(j)));// 十六进制转二进制
			}

			if (B.length() % 3 == 1) {
    
    // 补相应的0以便转换八进制
				B.insert(0, "00");
			} else if (B.length() % 3 == 2) {
    
    
				B.insert(0, "0");
			}
			int begin = 0, end = 3;
			while (end <= B.length()) {
    
    // 只有子串范围未超出,则转换八进制并拼接,并将子串窗口右移
				O.append(BtoO.get(B.substring(begin, end)));
				begin = end;
				end += 3;
			}
			if (O.charAt(0) == '0')// 去掉八进制的前导0
				out.println(O.substring(1));
			else
				out.println(O);
		}
		out.flush();
	}
}

运行结果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_50816725/article/details/112465564
今日推荐