编程18 进制转换
这题初看有点复杂,但只要理解进制转换的原理,加上一点字符串运用方法,就可以很顺畅的解决啦
一、题目简介

如图所示为本题要求,需要将一个N进制的数S转换成M进制,一共T个测试数据。
二、重点解析
2.1 进制转换
本题解题的核心就是理解进制转换的原理,由题意可知,N和M可为2~16的任意数字,也就是说不拘泥于我们学过的二进制、八进制和十六进制等。直接转换看似最简单,但一来大部分人并不清楚非常用进制间的直接转换,二来N和M的取值是任意的毫无规律可言,基本无法直接转换。
这个时候很容易想到在N进制和M进制之间设置一个中转点,即我们最熟悉的十进制。因为相比于任意进制间的转换,大部分人一定更熟悉任意进制转换为十进制,以及十进制转换为任意进制。
(1)任意进制N数num转换为十进制,其中数S为$$a_na_{n-1}...a_2a_1a_0$$
则转换为十进制后为
需注意的是10-15分别用A,B,C,D,E,F表示,需在超过十进制的进制中将数字转换成字母,反之计算时将字母转换成数字。
以二进制转十进制为例:
二进制数10110,转为十进制的公式为 0 * 2^0 + 1 * 2^1 + 1 * 2^2 + 0 * 2^3 + 1 * 2^4 = 14,二进制数一共5位,从右往左2的0次方到4次方分别乘以对应二进制上位数相加,得到十进制数,其他进制同理。
(2)十进制数num转换为任意进制数,其核心原理为“除M取余,逆序排列”
具体操作步骤为:
- num除以M得到商和余数
- 将商作为新一轮的十进制数,重复步骤1,直至商为0
- 余数是M进制上的数,得到的所有余数按得到顺序排列再逆序就是M进制数
- 若余数为10-15转换为字母
公式辅助记忆
设转换后的数字为$$b_kb_{k-1}...b_2b_1b_0$$
则$$ num = b_k * M^k + b_{k-1} * M^{k-1}...b_2 * M^2 + b_1 * M^1+b_0 * M^0 $$
以十进制转二进制为例
十进制数22转换为二进制:
- 22 / 2 = 11 ……0
- 11 / 2 = 5 …… 1
- 5 / 2 = 2 …… 1
- 2 / 2 = 1 …… 0
- 1 / 2 = 0 …… 1
所以转换后的数为10110
2.2 进制转换代码展示
(1)N进制转十进制
# N进制转十进制mid_num = 0temp = 0for j in S[::-1]:# 判断是否为字母if j >= 'A' and j <= 'Z':# ord函数得到字符的ASCII编码j = ord(j) - ord('A') + 10mid_num += int(math.pow(N, temp)) * int(j)temp += 1
- 用mid_num代表N进制到M进制的中转十进制数
- temp代表N的0到n次方,因为此段代码是包含在一段循环代码中的
- 通过ord函数得到字符ASCII编码实现字母转换成数字
- pow数学函数意为幂函数,括号内第一个数为底数,第二个数为指数
(2)十进制转M进制
# 十进制转M进制result = []while mid_num > 0:digit = mid_num % M if digit < 10:result.append(str(digit))else:# chr函数通过ASCII码值返回其对应的字符result.append(chr(digit - 10 + ord('A')))# 需注意是整除即将转换的进制Mmid_num //= Mresult = ''.join(reversed(result))
- result变成列表存储,便于用append不断增加得到的余数
- chr函数通过ASCII编码值返回对应字符,用于计算完对应数字并进行转换
- 需注意mid_num循环时整除的并非数字10而是要求的进制M
- 最后用reversed加join函数逆序排放
本题重点即进制转换,其中需要注意10-15代表A-F,其余按正常逻辑编写即可。
完整代码
import mathT = int(input())
for i in range(T):# S为N进制数,需转换成M进制数输出N,M = map(int, input().split())S = input()# N进制转十进制mid_num = 0temp = 0for j in S[::-1]:# 判断是否为字母if j >= 'A' and j <= 'Z':# ord函数得到字符的ASCII编码j = ord(j) - ord('A') + 10mid_num += int(math.pow(N, temp)) * int(j)temp += 1# 十进制转M进制result = []while mid_num > 0:digit = mid_num % M if digit < 10:result.append(str(digit))else:# chr函数通过ASCII码值返回其对应的字符result.append(chr(digit - 10 + ord('A')))# 需注意是整除即将转换的进制Mmid_num //= Mresult = ''.join(reversed(result))print(result)