Python: 十进制向不同进制数转化

问题背景

Py数:Py从小喜欢奇特的东西,而且天生对数字特别敏感,一次偶然的机会,他发现了一个有趣的四位数2992,
这个数,它的十进制数表示,其四位数字之和为2+9+9+2=22,它的十六进制数BB0,其四位数字之和也为22,
同时它的十二进制数表示1894,其四位数字之和也为22,啊哈,真是巧啊。
Py非常喜欢这种四位数,由于他的发现,所以这里我们命名其为Py数。
现在给你一个十进制4位数n,你来判断n是不是Py数,若是,则输出Yes,否则输出No。
如n=2992,则输出Yes; n = 9999,则输出No。

解决方法

问题的核心:实现十进制向任意进制的转化
参考aaronthon:python的十进制与任意进制的转换方法,对其中的conversion函数进行改进,具体如下:


def conversion(n, d):
    res=[]
    if n<d:
        return [n]
    else:
        while(n//d >= 1):
            res.append(n%d)
            n = n//d
        if(n%d !=0):
            res.append(n%d)
        return res[::-1]

其思路:

  • 当被转换化数小于当前进制时,直接输出即可;
  • 否则,采用$N = (N / d) * d + N%d $,进行进制转换(注:其输出是从地位到高位),所以上述改进中出现了:res[::-1].
    公式理解:以下图为例:

百度百科(图片来源于:百度百科)

十进制整数转换为二进制整数采用"除2取余,逆序排列"法。具体做法是:用2整除十进制整数,可以得到一个商和余数;
再用2去除商,又会得到一个商和余数,如此进行,直到商为小于1时为止,
然后把先得到的余数作为二进制数的低位有效位,后得到的余数作为二进制数的高位有效位,依次排列起来

完整程序:

# n:为被转化数
# d:为进制数
def conversion(n, d):
    res=[]
    if n<d:
        return [n]
    else:
        while(n//d >= 1):
            res.append(n%d)
            n = n//d
        if(n%d !=0):
            res.append(n%d)
        return res[::-1]

if sum(conversion(n,10))==sum(conversion(n,12))\
    and sum(conversion(n,10))==sum(conversion(n,16)):
    print('Yes')
else:
    print("No")

与内置进制转化数的对比

以123为例:

In [278]: conversion(123,2)
Out[278]: [1, 1, 1, 1, 0, 1, 1]

In [280]: bin(123)
Out[280]: '0b1111011'

In [281]: conversion(123,8)
Out[281]: [1, 7, 3]

In [282]: oct(123)
Out[282]: '0o173'

In [283]: conversion(123,16)
Out[283]: [7, 11]

In [284]: hex(123)
Out[284]: '0x7b'

从上述可以发现,通过conversion()函数转化的结果与内置函数的结果基本相同,唯一的区别是:当进制数大于10时,conversion仍然使用大于10小于进制数的余数,如123转16进制,而内置函数中关于超出来的一部分使用小写字母表示。为了保持与内置函数相同的输出类型,可以参考人民币转化通过建立字典即可。

任意进制的向10进制的还原

Python中使用内置函数int,如:

 int(0x7b)
Out[285]: 123

In [286]: int(0o173)
Out[286]: 123

In [287]: int(0b1111011)
Out[287]: 123

conversion()结果的还原,比较简单。假定输出结果为res=[a,b,c],res:为转化后的进制数,结果从高位到地位,d:进制数,求被转化数位 old_num按位加权求和即可。如:

\[old\_num=d^0*c+d^1*b+d^2*a \]


In [302]: def converBack(res,d):^M
     ...:     return sum([i*d**(len(res)-num-1) for num,i in enumerate(res)])
     ...:

In [303]: converBack([7,11],16)
Out[303]: 123

In [304]: converBack([1,7,3],8)
Out[304]: 123

In [305]: converBack([1,1,1,1,0,1,1],2)
Out[305]: 123


参考:
十进制转二进制

python的十进制与任意进制的转换

posted @ 2020-04-22 16:22  LgRun  阅读(1127)  评论(0编辑  收藏  举报