Skip to content

Commit b0b177e

Browse files
committed
added 128. Simplify Path
1 parent fc23ebe commit b0b177e

File tree

3 files changed

+102
-0
lines changed

3 files changed

+102
-0
lines changed

128. Simplify Path/README.md

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
这是个好题目,很有实际需求。
2+
3+
/a/./b/../../c/
4+
^^ (1)
5+
/a/b/../../c/
6+
^^^^ (2)
7+
/a/../c/
8+
^^^^ (2)
9+
//c/
10+
^^ (3)
11+
/c/
12+
^ (4)
13+
/c
14+
15+
我们只需要认真分析题目给出的第二个例子,就能发现几种变换方式:
16+
17+
1. `.` 代表当前目录,可忽略
18+
2. `..` 代表上一级目录,应退到前一个 `/`
19+
3. `//` 合并为 `/`
20+
4. 末尾`/`删除
21+
22+
显然,我们的进退应该按照 `/` 来区分,这是**关键**。我们应该对路径字符串进行以 `/` 的切割。
23+
然后一段一段的入栈出栈。接下来,我们倒过来写,看看 `/a/./b/../../c/` 入栈情况:
24+
25+
可分割为以下部分:
26+
27+
a | . | b | .. | .. | c
28+
29+
| character | action | stack |
30+
| :-------: | :----: | :----: |
31+
| a | push | a |
32+
| . | ignore | a |
33+
| b | push | a b |
34+
| .. | pop | a |
35+
| .. | pop | |
36+
| c | push | c |
37+
38+
最后将结果补充上 `/` 即可:`/c`.
39+
40+
-----
41+
42+
整理一下逻辑:
43+
44+
1. 遇到 `..` ,若 stack 不为空的话,pop 操作
45+
2. 继续,遇到 `.`, `..`, ` ` 这三种字符,无操作,continue.
46+
3. 出此之外,一律 push 操作。
47+
48+
注:分割后每一段字符串设为 `tmp`.
49+
50+
```cpp
51+
if (tmp == ".." && !stack.empty()) stack.pop_back();
52+
else if (tmp == "." || tmp == ".." || tmp == "") continue;
53+
else stack.push_back(tmp);
54+
```
55+
56+
然后将栈里面的字符串连接即可:
57+
58+
```cpp
59+
for (auto str : stack) { ret += "/" + str; }
60+
```
61+
62+
这里提示 C++ 中字符串分割的基本技巧:**使用 `istringstream`, 配合 `getline(iss, tmp, '/')`**
63+
64+
不多说,不超过十行。AC

128. Simplify Path/TEST.cc

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#define CATCH_CONFIG_MAIN
2+
#include "../Catch/single_include/catch.hpp"
3+
#include "solution.h"
4+
5+
TEST_CASE("Regular Expression Matching", "isMatch")
6+
{
7+
Solution s;
8+
9+
REQUIRE( s.simplifyPath("/home/") == "/home" );
10+
REQUIRE( s.simplifyPath("/a/./b/../../c/") == "/c" );
11+
REQUIRE( s.simplifyPath("/../") == "/" );
12+
REQUIRE( s.simplifyPath("/home//foo/") == "/home/foo" );
13+
REQUIRE( s.simplifyPath("/.") == "/" );
14+
REQUIRE( s.simplifyPath("/...") == "/..." );
15+
}

128. Simplify Path/solution.h

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include <string>
2+
using std::string;
3+
4+
#include <vector>
5+
using std::vector;
6+
7+
#include <sstream>
8+
using std::istringstream;
9+
10+
class Solution {
11+
public:
12+
string simplifyPath(string path) {
13+
string ret, tmp;
14+
vector<string> stack;
15+
for ( istringstream iss(path); getline(iss, tmp, '/'); ) {
16+
if (tmp == ".." && !stack.empty()) stack.pop_back();
17+
else if (tmp == "." || tmp == ".." || tmp == "") continue;
18+
else stack.push_back(tmp);
19+
}
20+
for (auto str : stack) { ret += "/" + str; }
21+
return ret.empty() ? "/" : ret;
22+
}
23+
};

0 commit comments

Comments
 (0)