Simplify a Unix-Style File Path
Problem
Given an absolute Unix path, return its canonical form: collapse any number of / separators into single ones, drop . segments, and let .. climb to the parent (but never above root). Split on / and walk the segments with a stack: .. pops if non-empty, . / empty skips, anything else pushes. Join the stack back with / at the end.
Input
"/home//foo/./bar/../baz/"Output
"/home/foo/baz"'.' is dropped, '..' undoes 'bar', empty segments collapse.
def simplify_path(path):
stack = []
for part in path.split("/"):
if part in ("", "."):
continue
if part == "..":
if stack:
stack.pop()
else:
stack.append(part)
return "/" + "/".join(stack)
function simplifyPath(path) {
const stack = [];
for (const part of path.split("/")) {
if (part === "" || part === ".") continue;
if (part === "..") {
if (stack.length) stack.pop();
} else {
stack.push(part);
}
}
return "/" + stack.join("/");
}
class Solution {
public String simplifyPath(String path) {
Deque<String> stack = new ArrayDeque<>();
for (String part : path.split("/")) {
if (part.isEmpty() || part.equals(".")) continue;
if (part.equals("..")) {
if (!stack.isEmpty()) stack.pop();
} else {
stack.push(part);
}
}
StringBuilder sb = new StringBuilder();
Iterator<String> it = stack.descendingIterator();
while (it.hasNext()) sb.append("/").append(it.next());
return sb.length() == 0 ? "/" : sb.toString();
}
}
string simplifyPath(string path) {
vector<string> stack;
string part;
stringstream ss(path);
while (getline(ss, part, '/')) {
if (part.empty() || part == ".") continue;
if (part == "..") { if (!stack.empty()) stack.pop_back(); }
else stack.push_back(part);
}
string out;
for (auto& p : stack) out += "/" + p;
return out.empty() ? "/" : out;
}