怎么说呢,其实这道题还挺简单的,但是边界情况有比较多,导致 Debug 了很久,真的是测试不规范,提交两行泪啊。
言归正传,思路就是使用一个 vector 来保存之前经历的路径,如果遇到需要忽略的合需要回退的就进行相应的操作,如果是其他种类的路径,就直接添加到 vector 之后。
然后就是有很多边界情况,比如 path 长度太小,最后回退到了根目录,给出的 path 最后不带“/”,所以导致解析错误等等。这些问题都需要先把测试用例写好再去调试代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| class Solution { public: string simplifyPath(string path) { if(path.size()<2) return "/"; path+='/'; vector<string*> canonical; int i=0,j=1; while(j<=path.size()){ if(path[j]!='/') j++; else{ if((j-i==2 && path[i+1]=='.')||(j-i==1)){ ; }else if(j-i==3 && path[i+1]=='.' && path[i+2]=='.'){ if(canonical.size()!=0) canonical.pop_back(); }else{ canonical.push_back(new string(path.begin()+i+1,path.begin()+j)); } i=j; j++; } } if(canonical.size()==0) return "/"; string ret=""; for(int i=0;i<canonical.size();i++){ ret+="/"; ret+=*(canonical[i]); } return ret; } };
|
看了一下 solutions C++ 10-lines solution,发现一个哥们太厉害了,把输入的 string 先转换成 stringstream,然后直接用 getline 当做 split 函数去做,代码就会简单很多(其实方法是一样的)
1 2 3 4 5 6 7 8 9 10 11 12
| string simplifyPath(string path) { string res, tmp; vector<string> stk; stringstream ss(path); while(getline(ss,tmp,'/')) { if (tmp == "" or tmp == ".") continue; if (tmp == ".." and !stk.empty()) stk.pop_back(); else if (tmp != "..") stk.push_back(tmp); } for(auto str : stk) res += "/"+str; return res.empty() ? "/" : res; }
|