问题描述
给定一个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
下运行程序,结果如下图所示。