如何将含小写字母数字及点的字符串压缩为混合大小写字母数字串?
短字符串的高效压缩方案(适配37→62符号映射)
因为输入仅含37种符号,输出支持62种符号,且字符串短无显著重复,核心思路是无损失的基数转换压缩——利用高基数符号的编码空间,直接将低基数的输入符号序列转换为更紧凑的高基数输出序列,无需重复模式检测。
具体实现步骤
1. 建立符号与整数的双向映射
先给每个输入符号分配唯一ID,同时给输出符号建立对应关系:
- 输入→ID映射:数字0-9对应0-9,小写a-z对应10-35,点字符
.对应36 - 输出→ID映射:数字0-9对应0-9,大写A-Z对应10-35,小写a-z对应36-61
可以用字典快速实现:
# 输入符号转ID input_map = {str(i): i for i in range(10)} input_map.update({chr(ord('a')+i): 10+i for i in range(26)}) input_map['.'] = 36 # 输出ID转符号 output_map = {i: str(i) for i in range(10)} output_map.update({10+i: chr(ord('A')+i) for i in range(26)}) output_map.update({36+i: chr(ord('a')+i) for i in range(26)})
2. 将输入字符串转为大整数
把每个输入字符替换成对应ID后,将整个序列按37进制拼接成一个大整数——相当于把低基数的数字转换成十进制大整数,这一步是压缩的核心:
def str_to_bigint(s): big_num = 0 for c in s: big_num = big_num * 37 + input_map[c] return big_num
3. 大整数转62进制输出字符串
把得到的大整数按62进制拆分,每个数位对应一个输出符号,反转后得到压缩结果:
def bigint_to_str(num): if num == 0: return output_map[0] chars = [] while num > 0: num, remainder = divmod(num, 62) chars.append(output_map[remainder]) return ''.join(reversed(chars))
4. 完整压缩/解压示例
# 压缩函数 def compress(s): if not s: return "" big_num = str_to_bigint(s) return bigint_to_str(big_num) # 解压函数(反向操作) def decompress(s): if not s: return "" # 先建立输出符号到ID的映射 reverse_output_map = {v: k for k, v in output_map.items()} big_num = 0 for c in s: big_num = big_num * 62 + reverse_output_map[c] # 再转37进制还原输入字符串 reverse_input_map = {v: k for k, v in input_map.items()} chars = [] while big_num > 0: big_num, remainder = divmod(big_num, 37) chars.append(reverse_input_map[remainder]) return ''.join(reversed(chars))
方案优势
- 无额外冗余:完全基于基数转换压缩,短字符串也不会有无效开销
- 计算高效:无需复杂的重复检测逻辑,压缩解压速度快
- 完全无损失:解压后能100%还原原字符串
内容的提问来源于stack exchange,提问作者Adrien
相关产品推荐
相关产品推荐

