蓝桥杯简单题之十六进制转八进制(JAVA版)

首先对等待程序猿成长之路系列的小伙伴们说声抱歉,春节来临,可能要拖更一段时间,但是草稿已经在写,发布将会于春节后进行发布
春节第一天闲着无聊打算找个蓝桥杯的题目练练手,诶嘿,这就找到一题,话不多说,上题

题目

在这里插入图片描述
题目很好理解,就是要输入n个数,将其从十六进制转成八进制。一般的做法也如这里提示所说。要先转成10进制后转成八进制,但我认为先转成10进制会浪费计算机的算力并且提高了算法的时间复杂度,这种转换是完全可以进行优化的。

我的优化算法思路

我的算法是直接将16进制转乘8进制,算法有如下几点要求:

  1. 输入的内容为字符串,这样可以进行大数运算
  2. 最多只能使用一重for循环,以降低算法的时空复杂度。
  3. 返回的值也为字符串

下面来介绍一下我的算法:

  1. 将输入的字符串转化为字符数组
  2. 从低位(即数组的最高位)开始,进行运算:
    1. 因为是从16进制转8进制,为了保持数据一致,八进制上每位数字的数可以认为是原数同一位置上的 2 的幂次倍,这样说可能比较难以理解,那我就举个例子,(10)16 = (16)10 = (20)8 这里 十六进制上的首位(从低位数起第2位)为1,到了八进制就为2,也就是 1 * 2的1次方,(100)16 = (256)10 = (400)10 ,这里 十六进制上的首位(从低位数起第3位)为1,到了八进制就为4,也就是 1 * 2的2次方,以此类推。
    2. 但是要注意,低位会像高位进位,这里的进位数字要进行保存,我们用incr参数进行保存,在进行换算时要加上低位向高位的进位。
    3. 此外当前位上的数字进行了转换(乘以了 2 的幂次倍) + 进位很可能超过8,这时候我们要进行取余运算获取最后的小于8的值即为八进制该位上的数字。而进位也要继续保存,方便下一步的运算。
    4. 按照步骤1-3计算从低位到高位上每一位的八进制结果,要注意的是,首位数字可能会有进位,这时就需要对进位进行处理,处理方法与步骤2-3步类似。

代码

package hexToOct;

public class HexToOct {
	/**
	 * 十六进制转八进制
	 * 原理:1. 从低位往高位处理,每升一位*2
	 * @param args
	 */
	private static String hexToOct(String hex) {
		char[] ch = hex.toCharArray(); //step1
		StringBuilder builder = new StringBuilder();
		int i = 0, incr = 0; // incr - 累进数, rest - 余数
		//step2
		for (int j = ch.length-1; j>= 0; j--) {
			int numb = 0;
			// 将十六进制转10进制
			if (ch[j] >= '0' && ch[j] <= '9') {
				numb = Integer.valueOf(ch[j] - '0');
			} else if(ch[j] >= 'A' && ch[j] <= 'F') {
				numb = Integer.valueOf(ch[j] - 'A') + 10;
			} else {
				System.out.println("请输入十六进制数");
				return null;
			}
			// 处理每一位上的数字
			numb = numb << (i++); // numb = numb * (2^i); i = i + 1;
			numb += incr;
			incr = numb / 8; // 求累进数,便于加入下一次的运算
			numb = numb % 8; // 求当前的余数
			builder.append(numb + "");
		}
		//考虑首位进位的情况
		int rest = 0;
		if (incr != 0) {
			while(incr > 0) {
				rest = incr % 8;
				incr = incr / 8;
				builder.append(rest + ""); 
			}
		}
		return builder.reverse().toString();
	}
	
	
	public static void main(String[] args) {
		System.out.println(hexToOct("8A24B"));
	}
}

运算结果

2121113

算法复杂度

O(n)

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zygswo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值