目录
- 1、题目描述:
- 2、思路:
- 3、代码实现:
- (1)python代码:
- (2)C++代码:
- 4、总结:
- 参考文献:
首先根据’/
'将path
进行split
,用res
保存简化后需要的文件名,对于每个元素进行分类讨论:
.
或者 空字符串 则跳过;..
说明需要返回上一级,即弹出一个文件名,但是这里有一个细节需要注意,只有res
非空的时候才能弹出,否则对于测试用例 '/../
'不能通过,因为此时的res为空;res
最后用’/
‘连接起来,并且在首部加上’/
'即可。
由于python提供
.split()
函数分割字符串,因此变得很简单,只是需要注意的是:.split()
函数默认是用空格分割的,分割之后会保存在列表中。
class Solution: def simplifyPath(self, path: str) -> str: l = path.split('/') res,i = [],0 while i<len(l): if l[i]=='..': if res: res.pop() # 这个if保证了res非空的情况 elif l[i]!='.' and l[i]!='': res.append(l[i]) i+=1 return '/'+'/'.join(res)
C++并没有提供自动分割的函数,那么我们需要自己去分割。这里使用了stringstream+getline来分割字符串,下面先介绍一下这两个怎么用:
getline
函数用于读取整行字符串。getline()
的API是:
istream& getline ( istream &is , string &str , char delim );
参数解释:
istream &is
表示一个输入流,例如cin
;string&str
表示把从输入流读入的字符串存放在这个字符串str
中;char delim
表示遇到这个字符停止读入,在不设置的情况下系统默认该字符为’\n
’,因此getline
函数遇到换行符会自动结束读取操作。(我们可以通过改变函数中第三个终止符参数对字符串进行分割。)因此,分割的思路是:先将读取的字符串保存在stringstream
流对象中,用getline()
函数读取字符串,遇到指定的终止符切割字符串。
估计还有点懵逼,看个例子吧!
#include <iostream> using namespace std; #include <string> #include <sstream> int main() { string txt = "/home/dir/file/"; stringstream ss(txt); string str; while (getline(ss, str, '/')) { cout << str << endl; } return 0; }
输出:
//第一行为空串,因为txt第一个字符是'/' home dir file
知道了怎么分割,现在我们就开始做这道题:
解题思路:
这里的思路和前面用python时稍微有点不同,因为python使用split()直接就分割了,无论是
..
还是...
,都分割开了,所以在遍历分开的列表时,就要判断一个点和两个点的情况了。
但是, C++需要我们自己分割,因此,我们在分割的时候就可以剔除掉一个点和两个点的情况,当然,也可以像python那样,先分割再判断,但是这样复杂度会高。
需要注意的是:getline在分割的时候,如果分割的那个字符左边或者右边没有字符,那么就会返回一个空串,因此下面的代码中才有空串的判断了。
用 /
来做分隔,考虑每个字符串的内容:
.
: 跳过..
而且数组不为空: 返回上一级,则删除数组最后一个元素..
’ 则为有效的目录名: 插入到数组里最后把数组组成结果即可
class Solution { public: string simplifyPath(string path) { stringstream ss(path); //把路径先保存到流中 vector<string> strs; strs.reserve(20); // 预留空间 string curr; // 从流中取出字符放入curr中 while (getline(ss, curr, '/')) { if (curr != "." && curr != "") { if (curr != "..") { strs.push_back(curr); } else if (!strs.empty()) { strs.pop_back(); } } } if (!strs.empty()) { string res = ""; for (string str : strs) { res.append("/"); res.append(str); } return res; } else { // 为空,直接返回 "/" return "/"; } } };
这道题,我首先想到的竟然是直接去遍历每一个字符。看完别人的答案,觉得应该先想到:分割字符串后再进行判断,如果能想到这里点,其实后面就不太难了。
https://leetcode-cn.com/problems/simplify-path/solution/cji-hu-shuang-bai-de-jie-fa-by-ffreturn-hs4c/