Given an absolute path for a file (Unix-style), simplify it.
For example,
path =
path =
path =
"/home/"
, => "/home"
path =
"/a/./b/../../c/"
, => "/c"
Corner Cases:
- Did you consider the case where path =
"/../"
?
In this case, you should return"/"
. - Another corner case is the path might contain multiple slashes
'/'
together, such as"/home//foo/"
.
In this case, you should ignore redundant slashes and return"/home/foo"
.
Updated(201309):
Analysis:
(1) Use a stack to store the path.(2) Use a int flag to store the '/' pair
(3) First remove the "//" in the path.
(4) meets ".", do nothing, meets ".." pop stack if not empty, other strings push into stack.
Code:
class Solution { public: string simplifyPath(string path) { // Start typing your C/C++ solution below // DO NOT write int main() function //Remove double "//" int i=0; while (i<path.size()-1){ if (path[i]=='/' && path[i+1]=='/'){ path.erase(i,1); }else{ i++; } } //Add a '/' in the end. if (path[path.size()-1]!='/'){path=path+"/";} //main part stack<string> dirs; string str=""; int flag =0; for (int i=0;i<path.size();i++){ if (path[i]=='/'){flag++;} if (flag==1){ str+=path[i];} if (flag==2){ if (str=="/.." && !dirs.empty()){ dirs.pop(); } if (str!="/." && str!="/.."){ dirs.push(str); } flag=1; str="/"; } } //Output Result if (dirs.empty()){return "/";} str=""; while (!dirs.empty()){ str=dirs.top()+str; dirs.pop(); } return str; } };
Analysis(old version):
The criterion is when meet "..", go to previous folder, meet ".", current folder, otherwise, go into next folder.
For implementation:
(1) function strtok(char*, const char*), note that " string.c_str() " returns "const char*" but not "char*", one way is to create a new char* with the same length (by char* = new char [length+1] ), and then use function "strcpy(target_char*, source_char*)".
(2) In the loop of getting strtok() " pth = strtok(NULL, "/") " NULL mean continues scanning previous call.
(3) Use "strcmp" to compare char* , where returns 0 if equals.
(4) Be careful with the output order of stack.
Code(old version):
class Solution { public: string simplifyPath(string path) { // Start typing your C/C++ solution below // DO NOT write int main() function stack<char*> st; //store folders //get token char* pth = new char [path.size()+1]; strcpy(pth,path.c_str()); char* tok = strtok(pth,"/"); while (tok!=NULL){ if (strcmp(tok,".")!=0){st.push(tok);} //if meet "." do nothing. if ((!st.empty())&&(strcmp(st.top(),"..")==0)){ //if meet "..", pop ".." and pop one more if available st.pop(); if (!st.empty()){st.pop();} } tok = strtok(NULL,"/"); } string res; //get result (be careful with the order of stack) while (!st.empty()){ res = "/" + string(st.top())+ res; st.pop(); } if (res.empty()) return "/"; return res; } };
like your solution, but would "erase" operation cost too much? Add a line [ if (i < path.size() - 1 && path[i] == path[i + 1])continue; ] will do the job
ReplyDelete