NG SWE · Phone Screen Coding

Bloomberg Atoi:字符串转整数的解析边界与溢出

题目仅给 123→123;先确定空白、符号、数字前缀和溢出契约,再给 32 位训练实现。

题目重点:题目仅给 123→123;先确定空白、符号、数字前缀和溢出契约,再给 32 位训练实现。

题意与假设

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

  • 展示的训练契约允许前导 ASCII 空格、可选 +/-、随后最长 ASCII 数字前缀;没有数字返回 0。
  • 训练版把结果截到 int32 [-2^31,2^31−1];题目没有规定 clamp、异常还是大整数,现场必须先问。

解题路线

  1. 用游标跳过前导空格、识别至多一个符号,接着逐位累积十进制数;遇非数字停止。
  2. 累积时按符号的允许绝对值上限提前截断,避免固定宽度语言先溢出再比较。
  3. 空串、全空格、只有符号、前导零、后缀文字、正负边界各手算一次。
  4. 若真实题意只接受纯数字字符串,可进一步简化为逐字符校验;不要把训练扩展误称原题要求。

手动走一遍

‘ -42tail’ 在训练版返回 -42;‘2147483648’ 截为 2147483647;‘123’ 返回 123。只有最后一个是题目提供的例子。

Python 参考实现

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

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

def atoi_training(text):
    """Training contract: spaces, optional sign, digit prefix, int32 clamp."""
    i = 0
    while i < len(text) and text[i] == " ":
        i += 1
    sign = 1
    if i < len(text) and text[i] in "+-":
        sign = -1 if text[i] == "-" else 1
        i += 1
    value = 0
    while i < len(text) and "0" <= text[i] <= "9":
        digit = ord(text[i]) - ord("0")
        value = min(value * 10 + digit, 2**31 if sign < 0 else 2**31 - 1)
        i += 1
    return sign * value

复杂度

扫描最多 n 个字符,O(n) 时间、O(1) 附加空间;Python 大整数在计算中仍可能暂增,但代码逐位截断。

易错点与追问

容易失分的边界

  • 不澄清 int32 溢出策略。
  • 接受 Unicode 数字却面试语言只支持 ASCII。
  • 符号出现两次仍解析。
  • 先乘再加在 C++/Java 固定整数里溢出。

继续深挖

  • 非法字符返回错误还是停止?
  • 支持十六进制或 Unicode 数字?
  • 若需要 64 位怎么改边界?
✓已复制微信号!