题目重点:给定cwd和目标路径返回词法规范绝对路径,处理重复斜杠、.、..及普通的多点文件名。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- cwd是绝对路径;target可绝对或相对。返回总以/开始,根目录为/,其余不以/结尾。
- 仅词法规范,不查询文件系统,不解析符号链接、~或环境变量。普通...与....是名字而不是父目录。
解题路线
- 若target以/开头忽略cwd;否则拼cwd/target。按/切段,空段或.跳过,..弹一个已保存目录但根处不再上移,其他原样push。
- 输出/加各段join。即使cwd本身含.或..,拼接后同一过程规范。不能用简单字符串replace消掉“..”,会破坏合法名称。
- 实际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和大小写规则,不能把/模型直接迁移。
