用多种ifelse很不好很复杂容易丢情况
class Solution {
public:
string simplifyPath(string path) {
stack<char> st;
string result;
int n = path.size();
while(n > 1 && (path[n-1] == '/' || path[n-1] == '.')){
if(n > 2 && path[n-2] == '.' && path[n-1] == '.' ){
break;
}
if(n > 2 && path[n-2] != '/' && path[n-1] == '.' ){
break;
}
n -- ;
}
for(int i = 0; i <= n-1; i++){
while(!st.empty() && st.top() == '/' && path[i] == '/'){
i++;
}
if(!st.empty() && st.top() == '/' && path[i] == '.' && (i + 1 >= n || path[i+1] =='/')){
i++;
continue;
}else if(!st.empty() && st.top() == '/' && path[i] == '.' && i+1 < n && path[i+1] == '.' && (i + 2 >= n || path[i+2] == '/')){
i += 2;
if(!st.empty()){
st.pop();
if(st.empty()){
st.push('/');
}
while(!st.empty() && st.top() != '/'){
st.pop();
}
}
continue;
}else{
st.push(path[i]);
}
}
if (!st.empty() && st.top() == '/' && st.size() > 1) {
st.pop();
}
for(int i = st.size();i>0;i--){
result = st.top() + result;
st.pop();
}
return result;
}
};
另一种方法 分割路径
分割路径:将路径按
/分割成多个部分。处理每个部分:
如果是
.或空字符串,跳过。如果是
..,表示返回上一级目录,需要弹出栈顶元素(如果有)。如果是普通目录名,将其压入栈中。
构建结果:将栈中的目录名按顺序拼接成规范路径。
stringstream 是 C++ 提供的专门用于处理字符串的 输入输出流类。
stringstream是C++标准库中的一个工具,用于将字符串作为流来处理。通过结合getline函数,可以方便地按指定分隔符(例如/)分割字符串。这里稍微提一下c++中 “流” 的概念。在C++中,将数据从一个对象到另一个对象的流动抽象为“流”。流在使用前要被创建,使用后要被删除。数据的输入与输出是通过 I/O 流实现的,cin 和 cout 是c++预定义的流类对象。
stringstream的常用操作
初始化:可以将一个字符串传递给
stringstream构造函数,初始化一个流对象。cpp
复制
std::stringstream ss("hello world");读取数据:可以使用
>>操作符从流中提取数据(类似于cin)。cpp
复制
std::string word; ss >> word; // word = "hello"写入数据:可以使用
<<操作符向流中写入数据(类似于cout)。cpp
复制
ss << " new data"; // ss的内容变为 "hello world new data"使用
getline按分隔符分割字符串
getline函数通常用于从输入流中读取一行数据,但它也可以指定一个分隔符(默认是换行符\n)。
getline的语法cpp
复制
std::getline(输入流, 存储结果的字符串, 分隔符);
const std::string& s
const:表示s是一个常量,不能在循环体内修改。
std::string&:表示s是一个引用(reference),而不是值的拷贝。这样可以避免不必要的字符串拷贝,提高性能。
s:是循环中当前元素的别名。
为什么不用
stack<string>?C++标准库中确实提供了
stack容器,但它是一个适配器(adapter),底层默认使用deque实现。虽然stack可以直接用于栈操作,但它的功能较为局限:
无法直接遍历:
stack不支持迭代器,无法直接遍历栈中的元素。而在本题中,我们需要遍历栈中的目录名来构建最终路径。灵活性不足:
stack只提供了push、pop、top等基本操作,无法像vector那样灵活地访问和操作元素。相比之下,
vector不仅支持栈的基本操作,还支持遍历、随机访问等更多功能,更适合本题的需求。
class Solution {
public:
string simplifyPath(string path) {
vector<string> stack;
stringstream ss(path);//初始化流函数
string segment;
string result;
while(getline(ss, segment, '/')){
if(segment == "" || segment == ".") continue;
if(segment == ".."){
if(!stack.empty()) stack.pop_back();
}
else stack.push_back(segment);
}
for(const string& s: stack){
result += "/" + s;
}
return result.empty() ? "/" : result;
}
};

668

被折叠的 条评论
为什么被折叠?



