SWE / MLE · Coding

Meta Unix cd与路径简化:相对路径、根边界和字面点号

给定cwd和目标路径返回词法规范绝对路径,处理重复斜杠、.、..及普通的多点文件名。

题目重点:给定cwd和目标路径返回词法规范绝对路径,处理重复斜杠、.、..及普通的多点文件名。

题意与假设

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

  • cwd是绝对路径;target可绝对或相对。返回总以/开始,根目录为/,其余不以/结尾。
  • 仅词法规范,不查询文件系统,不解析符号链接、~或环境变量。普通...与....是名字而不是父目录。

解题路线

  1. 若target以/开头忽略cwd;否则拼cwd/target。按/切段,空段或.跳过,..弹一个已保存目录但根处不再上移,其他原样push。
  2. 输出/加各段join。即使cwd本身含.或..,拼接后同一过程规范。不能用简单字符串replace消掉“..”,会破坏合法名称。
  3. 实际shell的cd可基于逻辑PWD或物理符号链接目标,含symlink时结果取决于-L/-P等规则;面试词法题不假装已验证真实目录存在。

手动走一遍

cwd=/a/b,target=../c//./d得到/a/c/d;target=/../../foo得到/foo;target=.../x得到/a/b/.../x。空target保持规范cwd。

Python 参考实现

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

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

def canonical_cd(cwd, target):
    """Lexical absolute Unix path; no filesystem, symlink, tilde, or environment expansion."""
    if not cwd.startswith('/'):
        raise ValueError("cwd must be absolute")
    path = target if target.startswith('/') else cwd + '/' + target
    parts = []
    for part in path.split('/'):
        if part in ('', '.'):
            continue
        if part == '..':
            if parts: parts.pop()
        else:
            parts.append(part)
    return '/' + '/'.join(parts)

复杂度

O(L)时间与O(L)段栈/输出空间,L为路径字符数。

易错点与追问

容易失分的边界

  • 绝对target仍附加cwd会错误指向相对目录。
  • 根处直接pop空栈会异常;连续多个..仍保持根。
  • 文档偶有结果foo的相对形式,必须先固定返回合同,不混用/foo。

继续深挖

  • 若返回物理路径,需要实际filesystem resolve及不存在目录的错误策略,不能仅靠字符串栈。
  • Windows盘符/UNC与Unix不同,另定grammar和大小写规则,不能把/模型直接迁移。
✓已复制微信号!