SWE · Onsite Coding 1

Pinterest next() 分块读行:分隔符跨 Chunk 怎么处理

针对 onsite 提供 next() 类和 one//ntw 等分块示例,逐字符保留分隔符前缀,恢复完整行并验证随机切块。

题目重点:针对 onsite 提供 next() 类和 one//ntw 等分块示例,逐字符保留分隔符前缀,恢复完整行并验证随机切块。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 训练版把题目描述中写出的 //n 当成三字符行分隔标记;若面试现场实际是转义后的换行符,应把 delimiter 改为 '\n'。
  • next_chunk() 返回 str 或在结束时返回 None;空字符串只是空 chunk。连续分隔符代表空行;末尾只有分隔符时不额外输出空行。

解题路线

  1. 逐字符读取 chunk,维护当前行字符和 pending 分隔符前缀。pending 可能跨多个 chunk 保留,不能在 chunk 末尾直接输出。
  2. 新字符使 pending 不再是分隔符前缀时,依次把不可能组成分隔符的前导字符转入当前行;若 pending 完整等于分隔符,就输出一行并清空。
  3. EOF 时将未完成的 pending 当普通内容追加,输出非空残行;若流正好停在分隔符后,不凭空增加一行。
  4. 训练实现可接受任意非空 delimiter;固定短 delimiter 情况逐字符处理接近线性,复杂长 delimiter 可使用 KMP 自动机。

手动走一遍

chunks=['one//ntw','o//n','three//nfour','//nfi','ve'] 拼起来是 one//ntwo//nthree//nfour//nfive,依次输出 one、two、three、four、five;第一个 chunk 末尾的 tw 必须等后续 o 才成 two。若分隔符在 '/' 与 '/n' 之间切开,也能识别。

Python 参考实现

下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。

代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。

"""Parse a multi-character line marker across arbitrary next() chunks."""


def read_lines(next_chunk, delimiter: str = "//n"):
    if not delimiter:
        raise ValueError("delimiter must be nonempty")
    line = []
    pending = ""
    while True:
        chunk = next_chunk()
        if chunk is None:
            break
        for character in chunk:
            pending += character
            while pending and not delimiter.startswith(pending):
                line.append(pending[0])
                pending = pending[1:]
            if pending == delimiter:
                yield "".join(line)
                line = []
                pending = ""
    line.extend(pending)
    if line:
        yield "".join(line)

复杂度

设总字符数 T、分隔符长度 D、最长一行 L;展示版前缀检查最坏 O(T·D²)(D=3 时按常数看 O(T)),当前行与 pending 占 O(L+D)。输出所有行本身需 O(T) 总字符。KMP 可把任意长分隔符优化到 O(T+D)。

易错点与追问

容易失分的边界

  • 对每个 chunk 独立 split,跨块分隔符和单词会被拆错。
  • 忽略 Python/Java split 对尾部空串的行为差异。
  • 把示例的 //n 未经说明地换成实际换行字符。
  • 在 EOF 时丢掉没有末尾分隔符的残行。

继续深挖

  • 连续两个分隔符是否要输出空行?
  • 如果 next() 可能返回极长且无分隔符的 chunk,如何控制内存?
  • 分隔符很长且前后缀重叠时,怎样用 KMP 保证线性扫描?
✓已复制微信号!