背景
总结所有进制转化问题
十进制转二十六进制
问题描述
在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 A⟶1B⟶2Z⟶26AZ⟶52
此时,进制转换公式如下
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)