模拟目录管理
题目描述
实现一个模拟目录管理功能的软件, 输入一个命令序列, 输出最后一条命令运行结果.
支持命令:
- 创建目录命令:
mkdir 目录名称
, 如mkdir abc
为在当前目录创建abc目录, 如果已存在同名目录则不执行任何操作. 此命令无输出. - 进入目录命令:
cd 目录名称
, 如cd abc
为进入abc目录, 特别地,cd ..
为返回上级目录, 如果目录不存在则不执行任何操作. 此命令无输出. - 查看当前所在路径命令:
pwd
, 输出当前路径字符串.
约束:
- 目录名称仅支持小写字母
- mkdir 和 cd 命令的参数仅支持单个目录, 如:
mkdir abc
和cd abc
; 不支持嵌套路径和绝对路径, 如mkdir abc/efg
,cd abc/efg
,mkdir /abc/efg
,cd /abc/efg
是不支持的. - 目录符号为
/
, 根目录/
作为初始目录. - 任何不符合上述定义的无效命令不做任何处理并且无输出
输入描述
输入 N 行字符串, 每一行字符串是一条命令.
输出描述
输出最后一条命令运行结果字符串.
备注
命令行数限制100行以内, 目录名称限制10个字符以内.
用例1
输入:
mkdir abc
cd abc
pwd
输入:
/abc/
说明: 在根目录创建一个abc的目录并进入abc目录中查看当前目录路径, 输出当前路径 /abc/
题解
Python
import string
import sys
class FileNode:
def __init__(self, path, parent=None):
# 当前目录的绝对路径
self.path = path
# 指向父目录节点
self.parent = parent
# 子目录节点, 默认为空
self.children = {}
# 创建特属的子节点, 指向父目录
if self.parent:
self.children[".."] = self.parent
def validate_folder_name(self, folder_name) -> bool:
# 检查目录名是否包含无效字符
for char in folder_name:
if char not in string.ascii_lowercase:
return False
return True
def mkdir(self, folder_name):
if not self.validate_folder_name(folder_name):
return False
# 检查相同的目录名是否已经存在
if folder_name in self.children:
return False
# 创建新的目录节点, 并存储到子目录中
path = self.path + folder_name + "/"
new_folder = FileNode(path, self)
self.children[folder_name] = new_folder
return True
def cd(self, folder_name):
# 进入到父目录
if folder_name == "..":
return True, self.parent
# 校验目录名
if not self.validate_folder_name(folder_name):
return False, self
# 未找到子目录
if folder_name not in self.children:
return False, self
return True, self.children[folder_name]
def main():
# 首先创建根目录
root = FileNode("/")
# 创建根目录的引用, 当前工作目录
cwd = root
# 然后依次读取输入, 如果输入无效, 则直接忽略, 并继续读取下一条输入
for line in sys.stdin:
line = line.strip()
if not line:
continue
# 解析命令
parts = line.split()
cmd = parts[0]
if cmd == "pwd":
# 打印当前的目录
if len(parts) == 1:
print(cwd.path)
elif cmd == "cd":
if len(parts) == 2:
# 切换工作目录
folder_name = parts[1]
ok, new_cwd = cwd.cd(folder_name)
if not ok:
print("[cd] Invalid command:", line)
else:
cwd = new_cwd
elif cmd == "mkdir":
# 创建子目录
if len(parts) == 2:
folder_name = parts[1]
ok = cwd.mkdir(folder_name)
if not ok:
print("[mkdir] Invalid command:", line)
if __name__ == "__main__":
main()
Rust
use std::collections::{HashMap, HashSet}; use std::io::{stdin, BufRead}; /// 目录节点 pub struct FolderEntry { /// 当前目录的绝对路径 path: String, /// 指向父节点 parent: String, /// 子节点 children: HashSet<String>, } pub type FolderMap = HashMap<String, FolderEntry>; impl FolderEntry { #[must_use] #[inline] pub fn new(path: String, parent: String) -> Self { Self { path, parent, children: HashSet::new(), } } fn validate_folder_name(folder_name: &str) -> bool { for chr in folder_name.chars() { if !chr.is_ascii_lowercase() { return false; } } true } pub fn mkdir(&mut self, folder_name: String) -> Result<Self, String> { if !Self::validate_folder_name(&folder_name) { return Err(folder_name); } if self.children.contains(&folder_name) { return Err(folder_name); } let path = Self::to_path(&self.path, &folder_name); self.children.insert(folder_name); Ok(Self::new(path, self.path.clone())) } fn to_path(path: &str, folder_name: &str) -> String { format!("{path}{folder_name}/") } pub fn cd(&self, folder_name: &str) -> Option<String> { if folder_name == ".." { return Some(self.parent.clone()); } if !Self::validate_folder_name(folder_name) { return None; } if self.children.contains(folder_name) { let path = Self::to_path(&self.path, folder_name); Some(path) } else { None } } } fn solution() { let root = FolderEntry::new("/".to_owned(), "/".to_owned()); let mut map = HashMap::new(); let mut cwd = root.path.clone(); map.insert(root.path.clone(), root); for line in stdin().lock().lines() { let line = line.unwrap(); let line = line.trim_ascii(); if line.is_empty() { continue; } let mut parts = line.split_ascii_whitespace(); match parts.next() { Some("pwd") => { if parts.next().is_none() { println!("pwd: {}", cwd); } } Some("cd") => { // 切换工作目录 if let Some(folder_name) = parts.next() { if parts.next().is_some() { continue; } if let Some(cwd_entry) = map.get_mut(&cwd) { if let Some(new_folder_name) = cwd_entry.cd(folder_name) { cwd = new_folder_name; } } } } Some("mkdir") => { // 创建子目录 if let Some(folder_name) = parts.next() { if parts.next().is_some() { continue; } if let Some(cwd_entry) = map.get_mut(&cwd) { if let Ok(new_folder) = cwd_entry.mkdir(folder_name.to_owned()) { map.insert(new_folder.path.clone(), new_folder); } } } } Some(_) | None => {} } } } fn main() { solution() }