字符串的编码与解码(TinyURL的增强版)
字数 1699 2025-12-15 01:42:23

字符串的编码与解码(TinyURL的增强版)

题目描述

设计一个算法来编码和解码一组字符串。编码规则需要将任意字符串映射为一个短字符串(类似短网址系统),且该映射必须可逆(即解码后能得到原字符串)。本题的增强点在于:

  1. 需要支持任意数量的字符串编解码,而不仅是单个URL。
  2. 编码生成的字符串应尽可能短,且避免冲突。
  3. 需考虑大规模输入场景(如数千万字符串)下的存储效率。

解题思路

核心思想:使用哈希表双向映射自定义短码生成策略

  • 编码时:为每个长字符串生成唯一短码,建立 长字符串→短码短码→长字符串 的双向映射。
  • 解码时:直接通过短码从映射中找回原字符串。
  • 增强点解决:
    • 递增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:编码流程

  1. 输入长字符串 long_str
  2. 检查 long2short 中是否已存在映射:
    • 若存在,直接返回对应的短码。
    • 若不存在:
      a. 将 id_counter 当前值作为ID。
      b. 将ID转换为62进制短码 short_code
      c. 将映射 long_str → short_codeshort_code → long_str 存入哈希表。
      d. id_counter 增加1。
      e. 返回 short_code

步骤4:解码流程

  1. 输入短码 short_code
  2. short2long 中查找对应的长字符串。
  3. 若存在则返回;否则返回空或错误提示(假设输入短码总是有效)。

步骤5:处理大规模数据

  • 内存限制:当映射数量极大时,可将哈希表分片存储到数据库(如Redis)。
  • 短码冲突:62进制转换保证唯一性,无需额外查重。
  • 分布式扩展:使用分布式ID生成器(如雪花算法)替代单机 id_counter

举例演示

假设初始 id_counter = 0,字符集为 "0-9a-zA-Z"(62进制)。

  1. 编码 "https://www.example.com/page1"

    • 首次出现,分配ID=0,62进制短码为 "0"(实际可补位为固定长度如6位,此处简化为最小形式)。
    • 存储映射:
      long2short["https://..."] = "0"
      short2long["0"] = "https://..."
    • 返回短码 "0"
  2. 编码 "https://www.example.com/page2"

    • 新字符串,分配ID=1,62进制短码为 "1"
    • 返回短码 "1"
  3. 解码短码 "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, "")

增强优化点

  1. 固定长度短码:将短码补位到固定长度(如6位),左侧补'0',保持统一格式。
  2. 自定义短码:允许用户自定义部分短码(需检查冲突)。
  3. 过期与清理:为短码添加TTL(生存时间),定期清理过期映射。
  4. 安全性:使用随机化ID或哈希(如SHA-256截断)避免猜测短码,但需处理冲突。

总结

本题通过哈希表双向映射ID进制转换实现了可逆的短字符串编码,平衡了短码长度、唯一性和性能。增强版重点在于支持海量字符串映射和可扩展存储,是实际系统(如短网址服务)的核心简化模型。

字符串的编码与解码(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" 。 编码 "https://www.example.com/page2" 新字符串,分配ID=1,62进制短码为 "1" 。 返回短码 "1" 。 解码短码 "1" 查 short2long["1"] 得到 "https://www.example.com/page2" 。 代码框架(Python示例) 增强优化点 固定长度短码 :将短码补位到固定长度(如6位),左侧补'0',保持统一格式。 自定义短码 :允许用户自定义部分短码(需检查冲突)。 过期与清理 :为短码添加TTL(生存时间),定期清理过期映射。 安全性 :使用随机化ID或哈希(如SHA-256截断)避免猜测短码,但需处理冲突。 总结 本题通过 哈希表双向映射 与 ID进制转换 实现了可逆的短字符串编码,平衡了短码长度、唯一性和性能。增强版重点在于支持海量字符串映射和可扩展存储,是实际系统(如短网址服务)的核心简化模型。