蓝桥杯 基础练习 十六进制转八进制(java) 不超时,100分

探讨如何高效地将长十六进制数转换为八进制数,解决超时问题,采用StringBuilder优化处理过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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

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

样例输入
  2
  39
  123ABC

样例输出
  71
  4435274

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

本来以为很简单, 直接读入字符串,转换成十进制的int,再转换成八进制, 测试样例通过了, 提交后是错的, 仔细看题后发现题目里说每个十六进制数长度不超过100000, 这么长, long long也装不下啊.
那只能用字符串保存了, 每一位16进制数对应着4位二进制数, 每3位二进制数对应一位八进制数, 我就老老实实的先把每位十六进制数转换成4位二进制的字符串, 一个十六进制数处理完后, 再转换成八进制, 写完提交, 结果超时了.

再改进一下, 容易发现每3位十六进制数对应4位八进制数. 所以可以每次处理3位十六进制数,转换成十进制后直接转换成4位八进制数, 为了方便, 在十六进制数的前面补0, 保证其长度为3的倍数, 这样写完之后发现还是超时.
还有什么地方能改进呢, 一番寻找之后终于想起了StringBuilder, 因为字符串很长, 需要频繁修改, StringBuilder修改的速度更快. 将所有的String换成StringBuilder后, 终于成功了. 由此可见, StringBuilder果然比String快的多啊…
下面贴上java代码:

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


public class Main {

	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		int n=scanner.nextInt();
		ArrayList<String> list=new ArrayList<String>();//用来保存要输出的字符串
		for (int k = 0; k < n; k++) {
			StringBuilder hexString=new StringBuilder();
			hexString.append(scanner.next());
			StringBuilder octString=new StringBuilder();
			while (hexString.length()%3!=0) {	//在输入的字符串前补0,确保长度是3的倍数
				hexString.insert(0,"0");
			}
			for (int i = 0; i < hexString.length(); i=i+3) {
				int d=0;
				for (int j = 0; j < 3; j++) {	//从十六进制转换成十进制
					char c=hexString.charAt(i+j);
					int num=0;
					if (c>='0'&&c<='9') {
						num=c-'0';
					}else {
						num=c-'A'+10;
					}
					d=d*16+num;
				}
				//从十进制转换成八进制
				octString.append(String.valueOf(d/512)+String.valueOf(d%512/64)+String.valueOf(d%64/8)+String.valueOf(d%8));
			}
			int i=0;
			while (octString.charAt(i)=='0') {//去掉开头的0
				i++;
			}
			list.add(octString.substring(i));
		}
		for (String str:
			 list) {
			System.out.println(str);
		}
		
		
		
	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值