题目描述
题目来源:https://leetcode-cn.com/problems/simplify-path/
解题思路
题目解读
首先我们先对题目做一个大致的解读:我们要弄清楚到底要得到什么结果,也就是说简化路径,怎么简化。下面根据题目进行解读:
- 首先不能输出连续的两个‘//’
- 当遇到两个点时,返回上一级目录
- 当遇到一个点时,返回当前目录
起初的思路
到这里,我们题目解读的也差不多了,那么如何入手呢,因为这道题建议用栈,那么我们就使用栈,一开始我的思路就是:参考中缀表达式转后缀表达式,遇到除.和··外全部压入栈中,当遇到返回情况时,依照情况弹出来,代码如下:
string simplifyPath(string path) {
int t = path.length();
string element="";
if (t == 1)
element="/";
int top = -1;
element[++top] = '/';
int i = 1;
while (i < t - 1) {
if (element[top] == '/'&&path[i]=='/') {
i++;
continue;
}
if (path[i] == '.' && path[i + 1] == '/')
top -= 2;
else if (path[i] == '.' && path[i + 1] == '.') {
top--;
while (top > 0 && element[top] != '/')
top--;
}
else
element[++top] = path[i];
if (top < 0)
top = 0;
i++;
}
return element;
}
首先指出上面代码的错误之处:对于string类型的变量,下标操作符只能用来访问已知的string对象元素,而不能用来访问未确认的元素,所以不能用下标操作符来添加或者删除元素,编译器一开始不会报错,但是在执行的时候就会出现未知的错误
而且,上述代码对于目录分隔符/的处理并不是很好,所以就放弃了上述思路
正确的思路
首先直接上代码:
string simplifyPath(string path) {
vector<string> v;
string str;
istringstream iss(path);
while (getline(iss,str,'/')) { //while是以getline是否能取到有效输入来作为判断条件的
if (!str.empty() && str != "." && str != "..")
v.push_back(str);
else if (!v.empty() && str == "..")
v.pop_back();
}
if (v.empty())
return "/";//如果vector为空,则只输出/
str.clear();
for (auto& s : v) { //运用范围循环,将s与vector对象绑定
str += '/';//先输出目录分隔符
str += s;//再输出栈中的元素
}
return str;
}
上面运用了vector对象和getline来解决问题
首先讲一下大致的思路:先定义一个用于当作栈使用的容器,定义一个string类型的变量str,和一个输入流iss:
vector<string> v;//定义一个容器当作栈使用
string str;
istringstream iss(path);//将path转换为输入流
- 我们需要注意的是输入流istringstream,需要包含头文件#include<sstream>,下面是对C++输入流的一些补充:
C++引入了ostringstream、istringstream、stringstream这三个类,要使用他们创建对象就必须包含这个头文件。
- istringstream类用于执行C++风格的串流的输入操作。
- ostringstream类用于执行C风格的串流的输出操作。
- strstream类同时可以支持C风格的串流的输入输出操作。
- 对于while和getline一起使用也需要注意:while是以getline是否能取到有效输入来作为判断条件
while (getline(iss,str,'/')) { //while是以getline是否能取到有效输入来作为判断条件的
接下来就是判读条件:
if (!str.empty() && str != "." && str != "..")
v.push_back(str);
else if (!v.empty() && str == "..")
v.pop_back();
首先判断所取到的字符是否为空(因为是以‘/’为字符读取结束标志,那么就有可能读取到空字符),如果不为空字符,且字符不是返回当前目录和返回上一级目录,那么就把字符压栈,否则判断vector对象是否为空,如果不为空,那么就弹出栈操作。
总结:这道题重在要处理好目录分隔符‘/’(使用getline就能很好的处理关于目录分隔符的一些要求),然后就是返回当前目录操作符和返回上一级目录操作符的处理