字符串的编码与解码(TinyURL的增强版)
字数 1699 2025-12-15 01:42:23
字符串的编码与解码(TinyURL的增强版)
题目描述
设计一个算法来编码和解码一组字符串。编码规则需要将任意字符串映射为一个短字符串(类似短网址系统),且该映射必须可逆(即解码后能得到原字符串)。本题的增强点在于:
- 需要支持任意数量的字符串编解码,而不仅是单个URL。
- 编码生成的字符串应尽可能短,且避免冲突。
- 需考虑大规模输入场景(如数千万字符串)下的存储效率。
解题思路
核心思想:使用哈希表双向映射与自定义短码生成策略。
- 编码时:为每个长字符串生成唯一短码,建立
长字符串→短码和短码→长字符串的双向映射。 - 解码时:直接通过短码从映射中找回原字符串。
- 增强点解决:
- 用递增ID + 进制转换生成短码,确保唯一性且长度可控。
- 通过哈希表存储映射,实现O(1)的编解码操作。
- 存储大量数据时,可使用分布式哈希表或数据库持久化。
步骤详解
步骤1:设计数据结构
我们需要两个哈希表(或一个双向哈希表):
long2short:键为原始长字符串,值为生成的短码。short2long:键为短码,值为原始长字符串。
同时维护一个计数器id_counter,为每个新字符串分配唯一ID。
步骤2:短码生成策略
将数字ID转换为短字符串,常用62进制编码(0-9, a-z, A-Z共62字符):
- 例如ID
12345→ 62进制为"3d7"。 - 优点:短码长度随ID增长缓慢(6位短码可表示62^6≈568亿个字符串)。
步骤3:编码流程
- 输入长字符串
long_str。 - 检查
long2short中是否已存在映射:- 若存在,直接返回对应的短码。
- 若不存在:
a. 将id_counter当前值作为ID。
b. 将ID转换为62进制短码short_code。
c. 将映射long_str → short_code和short_code → long_str存入哈希表。
d.id_counter增加1。
e. 返回short_code。
步骤4:解码流程
- 输入短码
short_code。 - 从
short2long中查找对应的长字符串。 - 若存在则返回;否则返回空或错误提示(假设输入短码总是有效)。
步骤5:处理大规模数据
- 内存限制:当映射数量极大时,可将哈希表分片存储到数据库(如Redis)。
- 短码冲突:62进制转换保证唯一性,无需额外查重。
- 分布式扩展:使用分布式ID生成器(如雪花算法)替代单机
id_counter。
举例演示
假设初始 id_counter = 0,字符集为 "0-9a-zA-Z"(62进制)。
-
编码 "https://www.example.com/page1"
- 首次出现,分配ID=0,62进制短码为
"0"(实际可补位为固定长度如6位,此处简化为最小形式)。 - 存储映射:
long2short["https://..."] = "0"
short2long["0"] = "https://..." - 返回短码
"0"。
- 首次出现,分配ID=0,62进制短码为
-
编码 "https://www.example.com/page2"
- 新字符串,分配ID=1,62进制短码为
"1"。 - 返回短码
"1"。
- 新字符串,分配ID=1,62进制短码为
-
解码短码 "1"
- 查
short2long["1"]得到"https://www.example.com/page2"。
- 查
代码框架(Python示例)
class EnhancedTinyURL:
def __init__(self):
self.long2short = {}
self.short2long = {}
self.id_counter = 0
self.base62_chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
def _id_to_shortcode(self, num):
"""将数字ID转换为62进制字符串"""
if num == 0:
return self.base62_chars[0]
code = []
while num > 0:
num, rem = divmod(num, 62)
code.append(self.base62_chars[rem])
return ''.join(reversed(code))
def encode(self, long_str):
if long_str in self.long2short:
return self.long2short[long_str]
# 生成新短码
short_code = self._id_to_shortcode(self.id_counter)
# 存储双向映射
self.long2short[long_str] = short_code
self.short2long[short_code] = long_str
self.id_counter += 1
return short_code
def decode(self, short_code):
return self.short2long.get(short_code, "")
增强优化点
- 固定长度短码:将短码补位到固定长度(如6位),左侧补'0',保持统一格式。
- 自定义短码:允许用户自定义部分短码(需检查冲突)。
- 过期与清理:为短码添加TTL(生存时间),定期清理过期映射。
- 安全性:使用随机化ID或哈希(如SHA-256截断)避免猜测短码,但需处理冲突。
总结
本题通过哈希表双向映射与ID进制转换实现了可逆的短字符串编码,平衡了短码长度、唯一性和性能。增强版重点在于支持海量字符串映射和可扩展存储,是实际系统(如短网址服务)的核心简化模型。