以 Unix 风格给出一个文件的绝对路径,你需要简化它。或者换句话说,将其转换为规范路径。
在 Unix 风格的文件系统中,一个点(.
)表示当前目录本身;此外,两个点 (..
) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。更多信息请参阅:Linux / Unix中的绝对路径 vs 相对路径
请注意,返回的规范路径必须始终以斜杠 /
开头,并且两个目录名之间必须只有一个斜杠 /
。最后一个目录名(如果存在)不能以 /
结尾。此外,规范路径必须是表示绝对路径的最短字符串。
示例 1:
输入:"/home/" 输出:"/home" 解释:注意,最后一个目录名后面没有斜杠。
示例 2:
输入:"/../" 输出:"/" 解释:从根目录向上一级是不可行的,因为根是你可以到达的最高级。
示例 3:
输入:"/home//foo/" 输出:"/home/foo" 解释:在规范路径中,多个连续斜杠需要用一个斜杠替换。
示例 4:
输入:"/a/./b/../../c/" 输出:"/c"
示例 5:
输入:"/a/../../b/../c//.//" 输出:"/c"
示例 6:
输入:"/a//b////c/d//././/.." 输出:"/a/b/c"
1 #include "_000库函数.h" 2 3 4 //一开始不知道从何下手 5 //感觉是用栈,所以用vector来代替栈 6 7 class Solution { 8 public: 9 string simplifyPath(string path) { 10 vector<string>v; 11 string s = "";//用来记录临时路径 12 int n = 0;//记录‘.’的个数 13 for (int i = 0; i < path.size(); ++i) { 14 if (path[i] == '.') 15 ++n; 16 else if (path[i] != '/') {//记录次级目录 17 s.insert(s.end(), n, '.');//防止有些目录名是以.开头!! 18 n = 0; 19 s += path[i]; 20 } 21 else {//path[i] == '/' 22 if (n > 2) 23 s.insert(s.end(), n, '.'); 24 else if (n == 2 && !v.empty())//确保不是在根目录 25 v.pop_back();// 跳到上一级 26 27 n = 0; 28 if (s.size() > 0) 29 v.push_back(s); 30 s = ""; 31 } 32 33 } 34 if (n > 2) 35 s.insert(s.end(), n, '.'); 36 else if (n == 2 && !v.empty())//确保不是在根目录 37 v.pop_back();// 跳到上一级 38 if (s.size() > 0) 39 v.push_back(s); 40 s = ""; 41 for (int i = 0; i < v.size(); ++i)//之所以从1开始,是去除根目录的‘/’ 42 s = s + "/" + v[i]; 43 if (!s.empty())return s; 44 return "/"; 45 } 46 }; 47 48 //C++中有专门处理字符串的机制,我们可以使用stringstream来分隔字符串, 49 //然后对每一段分别处理,思路和上面的方法相似,参见代码如下: 50 // 51 52 class Solution { 53 public: 54 string simplifyPath(string path) { 55 string res, t; 56 stringstream ss(path); 57 vector<string> v; 58 while (getline(ss, t, '/')) { 59 if (t == "" || t == ".") continue; 60 if (t == ".." && !v.empty()) v.pop_back(); 61 else if (t != "..") v.push_back(t); 62 } 63 for (string s : v) res += "/" + s; 64 return res.empty() ? "/" : res; 65 } 66 }; 67 68 69 70 void T071() { 71 Solution s; 72 string str; 73 str = "/home/"; 74 cout << "输入:" << str << endl << "输出:" << s.simplifyPath(str) << endl; 75 str = "/../"; 76 cout << "输入:" << str << endl << "输出:" << s.simplifyPath(str) << endl; 77 str = "/home//foo/"; 78 cout << "输入:" << str << endl << "输出:" << s.simplifyPath(str) << endl; 79 str = "/a/./b/../../c/"; 80 cout << "输入:" << str << endl << "输出:" << s.simplifyPath(str) << endl; 81 str = "/a/../../b/../c//.//"; 82 cout << "输入:" << str << endl << "输出:" << s.simplifyPath(str) << endl; 83 str = "/a//b////c/d//././/.."; 84 cout << "输入:" << str << endl << "输出:" << s.simplifyPath(str) << endl; 85 str = "/..."; 86 cout << "输入:" << str << endl << "输出:" << s.simplifyPath(str) << endl; 87 88 }