写在前面
今天分享一道真实的面试题目。
题目是编码实现十进制到二进制的转换:
例如:
2 10
3 11
编码实现
python3 实现
def translate(num: int):
result = []
while num != 0:
result.append(str(num % 2))
num = num // 2
return "".join(result[::-1])
print(translate(3)) # 11
思考进阶一
上面的代码很简答的实现了十进制到二进制的逻辑,现在需要实现 十进制到八进制的转换、十进制到十六进制的转换、二进制转十进制等等。
例如:十六进制转十进制
15 15
a 16
13 19
其实过程也很简单 只要替换除数就可以实现,下面基于python3实现
# 十六进制的数字映射
temp = {
'10': 'a',
'11': 'b',
'12': 'c',
'13': 'd',
'14': 'd',
'15': 'f'
}
# 翻转字典
temp_reverse = {v: k for k, v in temp.items()}
def translate1(num: int, extra: int) -> str:
result = []
while num != 0:
result.append(str(num % extra))
num = num // extra
return "".join([temp.get(i, i) for i in result[::-1]])
def translate2(b: str, extra: int) -> int:
result = 0
for index, value in enumerate(b[::-1]):
result += int(temp_reverse.get(value, value)) * extra ** index
return result
# 结果验证 这里使用自带的 hex() 函数验证结果
for i in range(14, 20):
b = translate1(i, 16)
o = translate2(b, 16)
print(hex(i)[2:], "".join(b), i, o)
# 结果
"""
e d 14 14
f f 15 15
10 10 16 16
11 11 17 17
12 12 18 18
13 13 19 19
"""
图解计算过程
对应的十进制转换二进制的过程其实就是除法取余数的过程(除数为对应的进制),如图使用倒除法记录余数,最后倒叙余数既得结果;反之 二进制转换成十进制的过程就是对应余数乘法的过程。
思考进阶二
需求:有序生成excel列类似 A B C … Z AA AB; 即传入一个数字生成对应的序列表示 例如: 26 -> Z, 27 -> AA;
解题思路:
- 题目类似进制的转换 27进制的数据。
- 不同的地方是不会 各个位数的取值范围可能不相同。
- 通过获取商与余数转换对应的值。
def num2xls_col(idx):
if idx < 1:
raise ValueError("Index is too small")
result = ""
while idx != 0:
idx, r = divmod(idx - 1, 26)
result = chr(r + ord('A')) + result
return result
# 验证结果
for num in range(1, 26 * 8):
if num % 26 in [0, 1, 2, 25, 24]:
print(num2xls_col(num), end=",")
elif num % 26 == 3:
print("...", end="")
# A,B,...X,Y,Z,AA,AB,...AX,AY,AZ,BA,BB,...BX,BY,BZ,CA,CB,...CX,CY,CZ,DA,DB,...DX,DY,DZ,EA,EB,...EX,EY,EZ,FA,FB,...FX,FY,FZ,GA,GB,...GX,GY,
看似是进制转化的问题,实践起来却有不太一样,不过本质上都是除法取余数 开始的版本实现是字典存储数字与字母的映射关系,巧用 ascii 码可能代码更加简单。
总结
- 对于这种看似简单的题目一定要考虑边界,比如开始的例子就没有考虑到小于零的数字。
- ascii 可以有效结果字母与数字的连续关系。
- 希望你可以按照我的顺序一步步理解我的解题思路。
- 类似的算法题一定要从简单的问题一步步思考,一步步总结。