[算法分析与设计] leetcode 每周一题: 071. Simplify Path



题目链接: 




题目大意:

给定一个 Unix 风格的 path, 给出一个简化的版本 ;

题中还注明了 对顶层目录 的假设, 见下方 例3 ;


例如: 给定: "/home/", 则输出应为: "/home" ;

例如: 给定: "/a/./b/../../c/", 则输出应为: "/c" ;

例如: 给定: "/../", 则输出应为: "/" ;




解题过程:

(1) 题意很简单, 由于关键是对 corner case 的处理, 所以我大致上就直接按工程的做法做了 ;

(2) 就用最老实的做法, 逐项处理 ; 针对 "当前目录" 符号 "./", 直接忽略 ; 针对 "父目录" 符号 "../" 考虑利用栈来处理 (中间还要假设顶层目录是 "/") ;




代码如下:

class Solution {
  public:
    using Path = string;

    Path withoutRedundantSlash( const Path & s ) {
        Path ret;
        ret.push_back( s.front() );
        for ( size_t i = 1; i < s.size(); i++ ) {
            if ( s[i] == '/' && s[i - 1] == '/' ) {
                continue;
            }
            ret.push_back( s[i] );
        }
        return ret;
    }
    Path withoutTailSlash( const Path & s ) {
        auto ret = s;
        while ( ret.size() > 1 && ret.back() == '/' ) {
            ret.pop_back();
        }
        return ret;
    }
    Path withoutRedundantDot( const Path & s ) {
        vector< Path > segments;
        size_t head = 0;
        for ( size_t i = head; i < s.size(); i++ ) {
            if ( s[i] == '/' ) {
                segments.push_back( s.substr( head, i - head ) );
                head = i + 1;
            }
        }
        if ( head < s.size() ) {
            segments.push_back( s.substr( head ) );
        }

        vector< Path > dirs;
        for ( size_t i = 0; i < segments.size(); i++ ) {
            auto d = segments[i];
            if ( d == ".." ) {
                if ( dirs.size() <= 1 ) {
                    // FIXME: ignore heading `./` case
                    continue;
                }
                dirs.pop_back();
            } else if ( d == "." ) {
                continue;
            } else {
                dirs.push_back( d + "/" );
            }
        }

        Path ret;
        for ( size_t i = 0; i < dirs.size(); i++ ) {
            auto d = dirs[i];
            ret += d;
        }
        return ret;
    }

    // FIXME: assume filepath
    Path simplifyPath( Path path ) {
        Path ret = path;
        // cerr << ret << endl;
        ret = withoutRedundantSlash( ret );
        // cerr << ret << endl;
        ret = withoutRedundantDot( ret );
        // cerr << ret << endl;
        ret = withoutTailSlash( ret );
        return ret;
    }
};




Runtime: 6 ms


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值