class Solution {
//1. skip // and ./
//2. when meet ../ pop
//3. keep record of word between /word/
public:
string simplifyPath(string path) {
stack<int> sk;
string p;
path.append("/"); // normalize the back slash in the end, so we can keep record of the last word
sk.push(0);
int s=0;
for (int i=1; i<path.size(); i++) {
if (path[i] == '/') {
if (path[i-1] == '/'
|| path[i-1] == '.' && (i-2 < 0 || path[i-2] != '.')) {
// skip double // or /./
s = i;
}
else if (path[i-1] == '.' && i-2 >= 0 && path[i-2] == '.') {
s = i;
if (sk.top() == 0) continue;
// popping one part
int e = sk.top(); sk.pop();
p.erase(sk.top(), e-sk.top());
}
else {
// add new part
p.append(path, s, i-s);
sk.push(p.size());
s = i;
}
}
}
return p.size() == 0 ? "/" : p;
}
};
second time
class Solution {
public:
bool checkValidFile(string str)
{
for(int i = 0; i < str.size(); ++i)
if((str[i] >= 'a' && str[i] <= 'z')
|| (str[i] >= 'A' && str[i] <= 'Z')) return true;
return false;
}
string simplifyPath(string path) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
stack<string> files;
int start = 0;
while(start < path.size())
{
int end = start;
while(end < path.size() && path[end] != '/') end++;//... case: "/a/.." ?
string tmp = path.substr(start, end-start);
//if(tmp.size() == 2 && tmp[0] == '.' && tmp[1] == '.' && !files.empty()) files.pop();
if(tmp == ".." && !files.empty()) files.pop();
else if(checkValidFile(tmp)) files.push(tmp);
start = end+1;
}
string ans;
stack<string> fileReverse;
while(!files.empty()) fileReverse.push(files.top()), files.pop();
while(!fileReverse.empty())
{
ans += "/";
ans += fileReverse.top();
fileReverse.pop();
}
if(ans.size() == 0) ans = "/";
return ans;
}
};