代码随想录 栈与队列:71. 简化路径
Table of Contents
题目描述
给你一个字符串 path ,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 ’/’ 开头),请你将其转化为 更加简洁的规范路径。
在 Unix 风格的文件系统中规则如下:
一个点 ’.’ 表示当前目录本身。 此外,两个点 ’..’ 表示将目录切换到上一级(指向父目录)。 任意多个连续的斜杠(即,’//’ 或 ’///‘)都被视为单个斜杠 ’/’。 任何其他格式的点(例如,’…’ 或 ’…’)均被视为有效的文件/目录名称。 返回的 简化路径 必须遵循下述格式:
始终以斜杠 ’/’ 开头。 两个目录名之间必须只有一个斜杠 ’/’ 。 最后一个目录名(如果存在)不能 以 ’/’ 结尾。 此外,路径仅包含从根目录到目标文件或目录的路径上的目录(即,不含 ’.’ 或 ’..’)。 返回简化后得到的 规范路径 。
思考
逐步寻找/,或者说以/分割,提取出来字符,若.或空就跳过。若..将栈元素弹出。若其余,则推入栈。栈里面是有效的路径的字符串。
如何以/分割字符串?可以是 stringstream 和 getline 结合
stringstream
stringstream 是 C++ 标准库中的一个类,属于<sstream>头文件。它允许你像操作流(如 cin、cout)一样操作字符串。常见用途包括:
-
分割字符串(如按某个分隔符拆分路径)
-
将字符串转换为其他类型(如 int、double)
示例:
#include <sstream>
#include <string>
using namespace std;
string s = "123 456";
stringstream ss(s);
int a, b;
ss >> a >> b; // a = 123, b = 456
getline
getline是一个函数,可以从输入流中读取一行内容,直到遇到指定的分隔符(默认是换行符 \n,但可以自定义)。
while (getline(ss, segment, '/')) {
// segment 是被 '/' 分割出来的每一段字符串
}
这里getline从stringstream ss中每次读取被 / 分隔的子串,赋值给segment
stringstream ss(path);:把字符串path包装成流,方便后续分割和读取。
getline(ss, segment, '/'):每次读取path中被 / 分隔的部分,直到读完。
这样可以很方便地处理路径、分割字符串等操作。
代码实现
class Solution {
public:
string simplifyPath(string path) {
stack<string> st;
stringstream ss(path);
string segment;
while (getline(ss, segment, '/')) {
if (segment.empty() || segment == ".") continue;
if (segment == "..") {
if (!st.empty()) st.pop();
} else {
st.push(segment);
}
}
string result;
vector<string> res;
while (!st.empty()) {
res.push_back(st.top());
st.pop();
}
for (auto it = res.rbegin(); it != res.rend(); ++it) {
result += "/" + *it;
}
return result.empty() ? "/" : result;
}
};