【趣学Python算法100例】数制转换

157 阅读4分钟

问题描述

给定一个M进制的数x,实现对x向任意一个非M进制的数的转换。

问题分析

要搞定这道题,关键在于学会不同数制之间的转换,主要是二进制、八进制、十六进制和十进制这几种。理解下面这几个概念非常重要:

  • 基数:就是在一个数制里能用的数字数量。比如,十进制就有10个数字(0到9),所以基数是10;二进制只有2个数字(0和1),基数就是2。
  • :每个数位上的数字代表的值的大小不一样,这就是权。在十进制里,个位的权是1(10的0次方),十位的权是10(10的1次方),依此类推。对一个M进制的数,数位从左到右的权分别是M的0次方、1次方、2次方...,小数点右边则是M的-1次方、-2次方这样减下去。
    转换方法简单说:
  • 从二进制、八进制、十六进制转到十进制,就是每个位上的数乘以它的权,然后全部加起来。
  • 十进制转成二进制、八进制或十六进制,整数部分不断除以基数取余数,从低位到高位;小数部分则是乘基数取整数,从高位到低位。
  • 二进制、八进制、十六进制之间转换,可以先转成十进制做中转,也可以直接根据它们之间的对应关系转换(比如,3个二进制位变成1个八进制位,4个二进制位变成1个十六进制位)。

算法设计

十六进制呢,就是用0到9还有A到F这些符号表示的,所以我们用一个专门放字符的数组来存它们。当你往里加数或者取数的时候,看起来都是一些字符,但是要换成别的进制时,这些字符就又要当作数字来用了。为了能在字符和它们代表的数字之间随便转换,我们做了设计两个自定义函数,一个叫char_to_number(),另一个是number_to_char()

我们想测验程序准不准确,通常会一次次重新跑程序,每次给不同的数。但现在咱们改一改,让程序一次性运行,但能接受好几组数据来检查。这个不难,加个圈圈(循环)就行,只要满足某个条件,就一直让你输数据;不符合了,就停止输入。这个条件就是看一个表达式的结果是不是0,我们用个叫flag的变量来帮忙,规则是这样的:“只要flag是1,你就继续输;变成0了,就不让输了,循环结束。”
简单来说,就是加个循环,用flag控制,flag为1就继续,为0就停。

完成代码

#!/usr/bin/python3
# -*- coding: utf-8 -*- 
# @author : liuhefei 
# @desc: 数制转换

# 将字符转换成数字
def char_to_num(ch):
    if ch >= '0' and ch <= '9':
        return int(ch)                              # 将数字字符转换成数字
    else:
        return ord(ch)                              # 将字母字符转换成数字


# 将数字转换为字符
def num_to_char(num):
    if num >= 0 and num <= 9:
        return str(num)                     # 将0~9之间的数字转换成字符
    else:
        return chr(num)                     # 将大于10的数字转换成字符


# 其他数制转换为十进制
def source_to_decimal(temp, source):
    decimal_num = 0                                 # 存储展开之后的和

    for i in range(len(temp)):      # 累加
        decimal_num=(decimal_num * source)+char_to_num(temp[i])

    return decimal_num


# 十进制转换为其他数制
def decimal_to_object(decimal_num, object):
    decimal = []
    while decimal_num:
        # 求出余数并转换为字符
        decimal.append(num_to_char(decimal_num % object))
        decimal_num //= object              # 用十进制数除以基数

    return decimal


# 修改余数数制
def output(decimal):
    f = len(decimal)-1
    while f >= 0:
        print(decimal[f], end='')
        f -= 1
    print()

if __name__ == '__main__':
    MAXCHAR = 101                                   # 允许的最大字符串长度
    flag = 1                                                # 存储是否退出程序的标志
    while flag:                                     # 利用输入的flag值控制循环是否结束
        print("转换前的数是:", end='')
        temp= input()
        print("转换前的数制是:", end='')
        source = int(input())
        print("转换后的数制是:", end='')
        object = int(input())
        print("转换后的数是:", end=’’)
        decimal_num = source_to_decimal(temp, source)
        decimal = decimal_to_object(decimal_num, object)
        output(decimal)
        print("继续请输入1,否则输入0:")
        flag = int(input())


运行结果

vscode下运行程序,结果如下图所示。