Medium!
題目描述:
給定一個文檔 (Unix-style) 的完全路徑,請進行路徑簡化。
例如,
path = "/home/"
, => "/home"
path = "/a/./b/../../c/"
, => "/c"
邊界情況:
- 你是否考慮了 路徑 =
"/../"
的情況?
在這種情況下,你需返回"/"
。 - 此外,路徑中也可能包含多個斜杠
'/'
,如"/home//foo/"
。
在這種情況下,你可忽略多余的斜杠,返回"/home/foo"
。
解題思路:
這道題讓簡化給定的路徑,光是根據題目中給的那一個例子還真不太好總結出規律,應該再加上兩個例子 path = "/a/./b/../c/"
, => "/a/c"和path =
"/a/./b/c/"
, => "/a/b/c",
這樣我們就可以知道中間是"."的情況直接去掉,是".."時刪掉它上面挨着的一個路徑,而下面的邊界條件給的一些情況中可以得知,如果是空的話返回"/",如果有多個"/"只保留一個。那么我們可以把路徑看做是由一個或多個"/"分割開的眾多子字符串,把它們分別提取出來一一處理即可。
C++解法一:
1 class Solution { 2 public: 3 string simplifyPath(string path) { 4 vector<string> v; 5 int i = 0; 6 while (i < path.size()) { 7 while (path[i] == '/' && i < path.size()) ++i; 8 if (i == path.size()) break; 9 int start = i; 10 while (path[i] != '/' && i < path.size()) ++i; 11 int end = i - 1; 12 string s = path.substr(start, end - start + 1); 13 if (s == "..") { 14 if (!v.empty()) v.pop_back(); 15 } else if (s != ".") { 16 v.push_back(s); 17 } 18 } 19 if (v.empty()) return "/"; 20 string res; 21 for (int i = 0; i < v.size(); ++i) { 22 res += '/' + v[i]; 23 } 24 return res; 25 } 26 };
還有一種解法是利用了C語言中的函數strtok來分隔字符串,但是需要把string和char*類型相互轉換,轉換方法請戳http://www.cnblogs.com/grandyang/p/4312273.html。除了這塊不同,其余的思想和上面那種解法相同。
C 解法一:
1 class Solution { 2 public: 3 string simplifyPath(string path) { 4 vector<string> v; 5 char *cstr = new char[path.length() + 1]; 6 strcpy(cstr, path.c_str()); 7 char *pch = strtok(cstr, "/"); 8 while (pch != NULL) { 9 string p = string(pch); 10 if (p == "..") { 11 if (!v.empty()) v.pop_back(); 12 } else if (p != ".") { 13 v.push_back(p); 14 } 15 pch = strtok(NULL, "/"); 16 } 17 if (v.empty()) return "/"; 18 string res; 19 for (int i = 0; i < v.size(); ++i) { 20 res += '/' + v[i]; 21 } 22 return res; 23 } 24 };
C++中也有專門處理字符串的機制,我們可以使用stringstream來分隔字符串,然后對每一段分別處理,思路和上面的方法相似。
C++ 解法二:
1 class Solution { 2 public: 3 string simplifyPath(string path) { 4 string res, t; 5 stringstream ss(path); 6 vector<string> v; 7 while (getline(ss, t, '/')) { 8 if (t == "" || t == ".") continue; 9 if (t == ".." && !v.empty()) v.pop_back(); 10 else if (t != "..") v.push_back(t); 11 } 12 for (string s : v) res += "/" + s; 13 return res.empty() ? "/" : res; 14 } 15 };