pub struct Solution;
Implementations§
Source§impl Solution
impl Solution
Sourcepub fn length_longest_path(input: String) -> i32
pub fn length_longest_path(input: String) -> i32
用 Rust 的 Iterator
写函数式的解法。
先把输入拆分,因为每个片断都包含了文件名,路径深度和目录文件类型,对片断预处理。因为字符串表示是顺序表示的,所以前后之间是需要处理的。详细步骤说明:
- 按
\n
切分输入split('\n')
- 把每个
\t\tfile_name
映射成(level, file_name_length, is_file)
,这里的level
从0
开始(即根目录 level 为0
)- 找到第一个不是
\t
的字符的位置,position 表示\t
个数,即 level 层级,剩下的即文件名,我们取其长度即可,同时判断是否为文件(文件名中是否带.
) - 如果没有
\t
说明是在根目录下的,即level
为0
- 找到第一个不是
- 计算每一个目录/文件名的长度(根据上一步生成的 tuple),因为每次分析都需要用到之前的路径在哪一层,所以需要用到 state 状态(栈),计算结果是每个目录/文件的长度,所以用
scan
- 初始状态是
[]
,这里的状态表示上一次的父目录的绝对路径长度,即[level_0_len, level_1_len, level_2_len, ...]
- 进入到当前目录/文件,需要弹出上一次的父目录,直到
parents
里只剩当前目录/文件的父级(这里用split_off(at)
来简化多次pop()
- 当前级别的目录/文件的长度就是剩下的
parents
里最后一个父目录的绝对路径长度和 + 当前文件名长度 - 如果当前是目录,则当前目录长度
push
入栈,注意需要+ 1
表示算上/
scan
函数的参数函数里,返回(abs_len, is_file
) (注:scan
函数相当于是fold
+map
,或者说map
带了个 state 状态)
- 初始状态是
- 经过上一步,转换的结果已经变成
(abs_len, is_file)
了,只要过滤掉不是文件的项 - 然后找出
max
就是结果了
这里除了 scan
中每一步过程中需要更新 parents
这个状态,其它地方没有任何的 mutable 变量。函数式编程的方式逻辑非常清晰,代码写起来也非常方便,可读性高,加上 immutable 使得安全性也非常好。关键是在 Rust 里用函数式的方法几乎不损失性能。
Auto Trait Implementations§
impl Freeze for Solution
impl RefUnwindSafe for Solution
impl Send for Solution
impl Sync for Solution
impl Unpin for Solution
impl UnwindSafe for Solution
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more