代码(一) 进制转换

背景

总结所有进制转化问题

十进制转二十六进制

问题描述

在Excel中,列的名称是这样一个递增序列:A、B、C、…、Z、AA、AB、AC、…、AZ、BA、BB、BC、…、BZ、CA、…、ZZ、AAA、AAB…。我们需要将上述列名序列和以下自然数序列相互转换:1、2、3、…。

问题分析

正常而言,一个十进制数可以如下转换为二十六进制数

n u m = a 0 × 2 6 0 + a 1 × 2 6 1 + a 2 × 2 6 2 + . . . . num = a_{0} \times 26^{0} + a_{1} \times 26^{1} + a_{2} \times 26^{2} + .... num=a0×260+a1×261+a2×262+....

其中 a i ∈ [ 0 , 25 ] a_{i} \in [0, 25] ai[0,25]。从题意可知,现在对应关系为

A ⟶ 1 B ⟶ 2 Z ⟶ 26 A Z ⟶ 52 A \longrightarrow 1 \\ B \longrightarrow 2 \\ Z \longrightarrow 26 \\ AZ \longrightarrow 52 A1B2Z26AZ52

此时,进制转换公式如下

n u m = b 0 × 2 6 0 + b 1 × 2 6 1 + b 2 × 2 6 2 + . . . . num = b_{0} \times 26^{0} + b_{1} \times 26^{1} + b_{2} \times 26^{2} + .... num=b0×260+b1×261+b2×262+....

其中 b i ∈ [ 1 , 26 ] b_{i} \in [1, 26] bi[1,26]。因此原始问题转化为,如何从公式一转化为公式二。在进制转化时,使用辗转相除法。首先考虑余数的区别:

  • b 0 = 1 , 2 , . . . , 25 b_{0} = 1,2,...,25 b0=1,2,...,25时, a 0 = b 0 a_{0} = b_{0} a0=b0
  • b 0 = 26 b_{0} = 26 b0=26时, a 0 = 0 a_{0} = 0 a0=0

此外,商的区别可以通过减掉 b 0 × 2 6 0 b_{0} \times 26_{0} b0×260消减。

代码

def func(K):
  remain = K
  buff = []
  while(remain > 0):
    mod = remain % 26
    mod = mod if mod != 0 else 26
    buff.append(mod)
    remain = int((remain - mod) / 26)
  buff = [chr(ord('A') + v - 1) for v in buff]
  return "".join(buff[::-1])

十进制转十六进制

问题解析

问题比较简单,直接使用辗转相除法即可。另外,移位运算可以简化计算流程。

代码

def func(k):
  index2char = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F']
  remains = k
  buff = []
  while(remains > 0):
    buff.append(remains & 15)
    remains = remains >> 4
  buff = [index2char[v] for v in buff[::-1]]
  return "".join(buff)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值