蓝桥杯刷题2——十六进制转八进制

1 题目

题目:十六进制转八进制
问题描述
  给定n个十六进制正整数,输出它们对应的八进制数。
  
输入格式
  输入的第一行为一个正整数n (1<=n<=10)。
  接下来n行,每行一个由09、大写字母AF组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。

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

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


2 解题过程

2.1 第一版代码

偷懒直接使用java的转换函数写出了第一个版本,尝试提交。

import java.util.Scanner;

public class Main {
	public static void main(String[] args) { 
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();
		scanner.nextLine(); // 获取nextInt之后的一个一个换行符
		for (int i = 0; i < n; i++) { 
			// 直接使用Integer里面封装好的转换函数
			// 先16进制转为10进制,再10进制转8进制
			System.out.println(Integer.toOctalString(Integer.parseInt(scanner.nextLine(), 16)));
		}
		scanner.close();
	}
}

自己测试了一下是没有问题的。但是提交上去直接显示运行错误了,下载输入数据看了下,
在这里插入图片描述
数据的确很大,毕竟题目也说16进制数在十万位以内。(但是第一行为啥n的数据没有换行呢?是不是txt文档的问题?)估计就是数据太长的原因,因为用java的函数期间把16进制转换为了10进制的int类型,10万位的16进制转换位10进制绝对不是int类型能容纳的下的。看来16转8就是比另外两个16转10,10转16要麻烦。

2.2 StringBuffer、StringBuilder、String

再去参考了一下别人的代码,还是得用字符串存储的方式。然后自己用String写了一下发现不行,就了解了一下StringBuffer、StringBuilder、String的区别。以前虽然知道C#中的String也是不可改变的,每次修改都是创建一个新的String。然而Java中String在创建之后是完全不能修改的。这就引出了可以修改的StringBuffer和StringBuilder。他们三个的区别大概如下。

  • String,创建之后不可修改。
  • StringBuffer,可修改,线程安全,速度较StringBuilder慢。
  • StringBuilder,可修改,线程不安全,速度较StringBuffer快。

现在的情况需要创建一个不停修改的字符串用StringBuilder就好的。

2.3 将16进制转为2进制的字符串

其实直接判断读取进来的字符,写好16进制和2进制的转换关系,把2进制的字符串接起来。

String hexNum = scanner.nextLine();
StringBuilder binaryNum = new StringBuilder();
for (int j = 0;j < hexNum.length(); j++) {
	switch (hexNum.charAt(j)) {
	case '0':binaryNum.append("0000");break;
	case '1':binaryNum.append("0001");break;
	case '2':binaryNum.append("0010");break;
	case '3':binaryNum.append("0011");break;
	case '4':binaryNum.append("0100");break;
	case '5':binaryNum.append("0101");break;
	case '6':binaryNum.append("0110");break;
	case '7':binaryNum.append("0111");break;
	case '8':binaryNum.append("1000");break;
	case '9':binaryNum.append("1001");break;
	case 'A':binaryNum.append("1010");break;
	case 'B':binaryNum.append("1011");break;
	case 'C':binaryNum.append("1100");break;
	case 'D':binaryNum.append("1101");break;
	case 'E':binaryNum.append("1110");break;
	case 'F':binaryNum.append("1111");break;
	default:break;
	}
}

2.4 将2进制的字符串转换为8进制

// 确保二进制字符串是3的倍数
while(binaryNum.length() % 3 != 0) {
	binaryNum.insert(0, '0'); // 当长度对3求余不等于0的时候在前面加一个0
}

// 转换为8进制
StringBuilder octNum = new StringBuilder();
for (int j = 0; j < binaryNum.length(); j += 3) {
	String temp = binaryNum.substring(j, j+3);
	switch (temp) { 
		// 每三个字符作为一个子串,进行判断和添加
		case "000": octNum.append("0"); break;
		case "001": octNum.append("1"); break;
		case "010": octNum.append("2"); break;
		case "011": octNum.append("3"); break;
		case "100": octNum.append("4"); break;
		case "101": octNum.append("5"); break;
		case "110": octNum.append("6"); break;
		case "111": octNum.append("7"); break;
		default: break;
	}
}

// 消除前导0
while(octNum.charAt(0) == '0') {
	octNum.deleteCharAt(0);	// 当第一个数是0的时候删除第一数
}

2.5 完整代码

终于运行成功了。531ms,42.92MB。感觉好高啊,感觉随时会超时。

import java.util.Scanner;

public class Main {
	public static void main(String[] args) { 
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();
		scanner.nextLine();
		
		for (int i = 0; i < n; i++) { 
			String hexNum = scanner.nextLine();
			StringBuilder binaryNum = new StringBuilder();
			for (int j = 0;j < hexNum.length(); j++) {
				switch (hexNum.charAt(j)) {
				case '0':binaryNum.append("0000");break;
				case '1':binaryNum.append("0001");break;
				case '2':binaryNum.append("0010");break;
				case '3':binaryNum.append("0011");break;
				case '4':binaryNum.append("0100");break;
				case '5':binaryNum.append("0101");break;
				case '6':binaryNum.append("0110");break;
				case '7':binaryNum.append("0111");break;
				case '8':binaryNum.append("1000");break;
				case '9':binaryNum.append("1001");break;
				case 'A':binaryNum.append("1010");break;
				case 'B':binaryNum.append("1011");break;
				case 'C':binaryNum.append("1100");break;
				case 'D':binaryNum.append("1101");break;
				case 'E':binaryNum.append("1110");break;
				case 'F':binaryNum.append("1111");break;
				default:break;
				}
			}
			
			while(binaryNum.length() % 3 != 0) {
				binaryNum.insert(0, '0');
			}
			
			StringBuilder octNum = new StringBuilder();
			for (int j = 0;j < binaryNum.length();j+=3) {
				String temp = binaryNum.substring(j, j+3);
				switch (temp) {
				case "000": octNum.append("0"); break;
				case "001": octNum.append("1"); break;
				case "010": octNum.append("2"); break;
				case "011": octNum.append("3"); break;
				case "100": octNum.append("4"); break;
				case "101": octNum.append("5"); break;
				case "110": octNum.append("6"); break;
				case "111": octNum.append("7"); break;
				default: break;
				}
			}
			
			while(octNum.charAt(0) == '0') {
				octNum.deleteCharAt(0);				
			}
			System.out.println(octNum);
		}
		scanner.close();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值