背景
总结所有进制转化问题
十进制转二十六进制
问题描述
在Excel中,列的名称是这样一个递增序列:A、B、C、…、Z、AA、AB、AC、…、AZ、BA、BB、BC、…、BZ、CA、…、ZZ、AAA、AAB…。我们需要将上述列名序列和以下自然数序列相互转换:1、2、3、…。
问题分析
正常而言,一个十进制数可以如下转换为二十六进制数
num=a0×260+a1×261+a2×262+.... num = a_{0} \times 26^{0} + a_{1} \times 26^{1} + a_{2} \times 26^{2} + .... num=a0×260+a1×261+a2×262+....
其中ai∈[0,25]a_{i} \in [0, 25]ai∈[0,25]。从题意可知,现在对应关系为
A⟶1B⟶2Z⟶26AZ⟶52 A \longrightarrow 1 \\ B \longrightarrow 2 \\ Z \longrightarrow 26 \\ AZ \longrightarrow 52 A⟶1B⟶2Z⟶26AZ⟶52
此时,进制转换公式如下
num=b0×260+b1×261+b2×262+.... num = b_{0} \times 26^{0} + b_{1} \times 26^{1} + b_{2} \times 26^{2} + .... num=b0×260+b1×261+b2×262+....
其中bi∈[1,26]b_{i} \in [1, 26]bi∈[1,26]。因此原始问题转化为,如何从公式一转化为公式二。在进制转化时,使用辗转相除法。首先考虑余数的区别:
- 当b0=1,2,...,25b_{0} = 1,2,...,25b0=1,2,...,25时,a0=b0a_{0} = b_{0}a0=b0
- 当b0=26b_{0} = 26b0=26时,a0=0a_{0} = 0a0=0
此外,商的区别可以通过减掉b0×260b_{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)