LeetCode 71. Simplify Path
Unix-style的path中,"."表示当前目录下的子目录,".."表示返回上一级目录,"..."的话保留(Input:"/..." Expected answer:"/...")。
因此维护一个stack,存放路径中文件夹的名字name,将path打散(split)后,一段段读入,如果是"."则继续读入下一段,如果是".."则将name的顶端pop掉,注意此处要检测name是否为空,因为输入有"/../",如果这两种都不是就压入name栈中。
自己写了个split函数,把path按"/"分开,因为有检测tmp是否为空,所以nodes里的所有string均不为空。注意split中for循环后,如果tmp不为空要压入nodes中(path最后一部分可能为“/abcd")。
最后如果name栈为空,res设为"/",否则将栈内依次加入res。
注意!name.empty()的位置,不能写成if(nodes[i] == ".." && !name.empty()),否则".."会被压入name中。
1 class Solution { 2 public: 3 void split(string str, char ch, vector<string>& nodes){ 4 string tmp = ""; 5 for(int i = 0; i < str.length(); ++i){ 6 if(str[i] == '/'){ 7 if(tmp != ""){ 8 nodes.push_back(tmp); 9 } 10 tmp = ""; 11 } 12 else { 13 tmp += str[i]; 14 } 15 } 16 if(tmp != "")//input: path = "/..." expected:"/..." 17 nodes.push_back(tmp); 18 19 } 20 string simplifyPath(string path) { 21 vector<string> nodes; 22 split(path, '/', nodes); 23 stack<string> name; 24 for(int i = 0; i < nodes.size(); ++i){ 25 if(nodes[i] == ".") continue;//nodes[i] == "" || 26 if(nodes[i] == ".."){//input: path = "/../" 27 if(!name.empty()) 28 name.pop(); 29 } 30 else 31 name.push(nodes[i]); 32 } 33 string res = ""; 34 while(!name.empty()){ 35 res = "/" + name.top() + res; 36 name.pop(); 37 } 38 if(res.empty()) res = "/"; 39 return res; 40 } 41 };
另外一种split的写法,时间相同,注意这种写法nodes中的内容可能为空,因此读入nodes[i]时要检测是否为空,为空则继续(Input:"///" Expected answer:"/")。
1 class Solution { 2 public: 3 4 void split(string s, char delim, vector<string>& nodes) { 5 string temp; 6 stringstream ss; //here 7 ss.str(s); //here 8 while(getline(ss, temp, delim)) { 9 nodes.push_back(temp); 10 } 11 } 12 string simplifyPath(string path) { 13 vector<string> nodes; 14 split(path, '/', nodes); 15 stack<string> name; 16 for(int i = 0; i < nodes.size(); ++i){ 17 if(nodes[i] == "" || nodes[i] == ".") continue;// 18 if(nodes[i] == ".."){//path = "/../" 19 if(!name.empty()) 20 name.pop(); 21 } 22 else 23 name.push(nodes[i]); 24 } 25 string res = ""; 26 while(!name.empty()){ 27 res = "/" + name.top() + res; 28 name.pop(); 29 } 30 if(res.empty()) res = "/"; 31 return res; 32 } 33 };
总结一下,个人认为比较特殊的输入和标准输出:
Input Expected answer
"///" "/"
"/..." "/..."
"/../" "/"