#P2304. 第2题-绝对路径
-
1000ms
Tried: 471
Accepted: 198
Difficulty: 4
所属公司 :
华为
时间 :2024年9月11日-留学生
-
算法标签>模拟
第2题-绝对路径
题面解释:
在Linux系统中,用户通过cd命令来切换工作目录。给定一个当前工作目录的绝对路径和一个相对路径命令,要求输出执行该命令后用户的新工作目录,且以最简洁的绝对路径形式表示,同时还需输出在命令执行过程中经过的最深目录层级数。输入包括当前工作目录的绝对路径和cd命令的相对路径,输出则包含用户新目录的绝对路径和最深层级数的两个数值。例如,若输入为/home/hello和cd .././/world/,则输出为/home/world和2,表示最终目录和经过的最深层级数。
思路
使用栈来模拟路径变化是通过利用栈的后进先出(LIFO)特性来实现文件系统的路径导航。首先,将当前路径和目标路径用“/”分割为路径片段,并依次处理。当前路径中的有效目录名依次入栈,表示进入对应的子目录;遇到“..”时,栈顶元素弹出,表示返回上一级目录。对于目标路径的处理,如果是有效目录,则入栈;如果是“..”,则弹出栈顶目录。在操作过程中,栈的最大深度反映了所到达的最大目录层级。
题解
在Linux系统中,路径的管理和切换非常重要。我们可以通过栈结构来模拟路径变化,利用栈的后进先出(LIFO)特性来实现文件系统的路径导航。首先,我们将当前路径和目标路径用“/”进行分割,得到路径片段。对于当前路径中的有效目录名,我们依次入栈,表示进入对应的子目录;遇到“..”时,表示返回上一级目录,因此弹出栈顶元素。对目标路径的处理同样适用:如果是有效目录名,则入栈;如果是“..”,则弹出栈顶目录。在路径操作的过程中,栈的最大深度将反映出用户所到达的最大目录层级数,包括当前目录和最终目录。最终,我们将栈中的内容拼接成绝对路径,并输出最简洁的形式。
代码解读
- 输入处理:通过
getline函数读取当前路径和命令输入,并将路径字符串按斜杠“/”分割,得到各个目录名片段。 - 路径管理:使用栈(这里用向量实现)来处理路径的变化,包括进入新目录和返回上级目录的操作。
- 层级深度:在处理路径的过程中,通过更新层级深度的变量,记录下路径的最大深度。
- 最终输出:在处理完成后,将栈中的内容拼接成最简洁的绝对路径,并输出最终的路径和层级深度。
代码
python
# 读取当前路径输入
s = input()
# 将当前路径按 "/" 分割为列表
s = list(s.split("/"))
# 弹出第一个元素(根目录前的空字符串)
s.pop(0)
# 读取需要切换的目标路径,目标路径的前缀忽略
_, ss = input().split()
# 将目标路径按 "/" 分割为列表
ss = ss.split("/")
# 初始化深度为当前路径的层级数
dep = len(s)
# 如果当前路径的第一个元素为空字符串,表示根目录,深度置为 0
if s[0] == "":
dep = 0
# 遍历目标路径中的每个部分
for x in ss:
# 跳过空字符串,防止多余的 "/"
if x == "":
continue
# 如果不是当前目录符号 "."
if x != ".":
# 如果是返回上一级目录符号 ".."
if x == "..":
# 如果栈不为空,弹出栈顶元素(返回上一级目录)
if len(s) > 0:
s.pop()
else:
# 否则,将该路径部分入栈(进入该目录)
s.append(x)
# 更新最大深度为当前栈的最大长度
dep = max(dep, len(s))
# 初始化结果路径为空字符串
res = ""
# 遍历栈中的路径部分,构造最终路径
for x in s:
if x != "":
res = res + "/" + x
# 如果路径为空,表示根目录,设置结果为 "/"
if res == "":
res = "/"
# 输出最终的路径
print(res)
print(dep)
java
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 读取当前路径并按 "/" 分割为列表
String input = sc.nextLine();
String[] pathSegments = input.split("/");
List<String> path = new ArrayList<>();
for (String segment : pathSegments) {
if (!segment.isEmpty()) {
path.add(segment);
}
}
// 读取需要切换的目标路径
input = sc.nextLine();
int pos = input.indexOf(' ');
String newPath = input.substring(pos + 1);
String[] newPathSegments = newPath.split("/");
// 初始化深度为当前路径的层级数
int dep = path.size();
// 遍历目标路径中的每个部分
for (String x : newPathSegments) {
if (x.isEmpty()) continue;
if (x.equals("..")) {
if (!path.isEmpty()) {
path.remove(path.size() - 1);
}
} else if (!x.equals(".")) {
path.add(x);
dep = Math.max(dep, path.size());
}
}
// 构造最终路径
StringBuilder res = new StringBuilder();
for (String x : path) {
if (!x.isEmpty()) {
res.append("/").append(x);
}
}
// 如果路径为空,表示根目录
if (res.length() == 0) {
res.append("/");
}
// 输出最终路径和深度
System.out.println(res.toString());
System.out.println(dep);
sc.close();
}
}
c++
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
// 读取当前路径并按 "/" 分割为路径片段
string input;
getline(cin, input); // 获取当前工作目录的绝对路径
stringstream ss(input);
vector<string> path; // 用于存储路径片段
string segment;
// 将路径按"/"分割并存入path向量中
while (getline(ss, segment, '/')) {
if (!segment.empty()) path.push_back(segment); // 跳过空段
}
// 读取需要切换的目标路径
getline(cin, input); // 获取cd命令
size_t pos = input.find(' '); // 找到cd和路径之间的空格
string newPath = input.substr(pos + 1); // 提取目标路径
stringstream ssNew(newPath);
vector<string> ssSegments; // 存储目标路径的片段
// 将目标路径按"/"分割并存入ssSegments向量中
while (getline(ssNew, segment, '/')) {
ssSegments.push_back(segment);
}
// 初始化深度为当前路径的层级数
int dep = path.size(); // 记录当前路径的层级数
if (path.size() > 0 && path[0].empty()) dep = 0; // 特殊情况处理
// 遍历目标路径中的每个部分
for (const string &x : ssSegments) {
if (x.empty()) continue; // 跳过空段
if (x != ".") { // "."表示当前目录,不做处理
if (x == "..") { // ".."表示上一级目录
if (!path.empty()) path.pop_back(); // 弹出栈顶元素
} else {
path.push_back(x); // 有效目录名入栈
}
dep = max(dep, (int)path.size()); // 更新最大深度
}
}
// 构造最终路径
string res;
for (const string &x : path) {
if (!x.empty()) res += "/" + x; // 拼接路径
}
// 如果路径为空,表示根目录
if (res.empty()) res = "/";
// 输出最终的路径
cout << res << endl; // 输出最简洁的绝对路径
cout << dep << endl; // 输出最大目录层级数
return 0;
}
题目内容
Linux系统中,绝对路径是从根目录开始的完整路径,即以'\'开头,相对路径是从当前工作目录开始的路径,以'.'、'..'或当前目录的子目录名开始。某用户便用'cd' 相对路径"的指令来切换工作目录,假设其使用的相对路径包含如下部分:
-
一个点'.'表示当前目录;
-
两个点'..'表示上一级目录,根目录的上一级仍然是根目录;
-
斜杠'/'用于分割目录,连续的多个斜杠等价于单个斜杠;
其他字符串均代表目录名,如'...'、'hello',且假设目录都存在;
请计算出用户在使用'cd 相对路径'指令后的工作目录,要求:
- 以绝对路径的形式输出,即以/开始;
- 以最简洁形式输出;最简洁形式指的是路径中没有冗余部分,即没有'.'、'..'、'//',不以'/'结尾; 另外,假设cd指令执行过程中,会依次进入每一级目录,请给出,经过的最深的目录的层级数,包括当前目录和最终目录,假设根目录'/'为0层。
输入描述
第一行为当前工作目录的绝对路径,为最简洁形式;字符数范围[1,100];
第二行为用户执行的cd相对路径命令,cd和相对路径之间有一个空格隔开,相对路径的字符数范围[1,100],注意cd和空格还有3个字符;
输出描述
第一行为用户执行'cd相对路径'指令后的当前工作目录,要求以最简洁的绝对路径形式输出。
第二行为指令过程中经过的最深目录层级数。
样例1
输入
/home/hello
cd .././/world/
输出
/home/world
2
说明
指令执行过程中进入的目录依次为:/home/hello、/home、/home/world,最终目录为/home/world,最深层次为2。
样例2
输入
/home/hello
cd world/.../../.
输出
/home/hello/world
4
说明
...也是合法目录名:
指令执行过程中进入的目录依次为:$/home/hello、/home/hello/world、/home/hello/world/...、/home/hello/world$,最终目录为/home/hello/world,最深层级为4