#P2304. 第2题-绝对路径
          
                        
                                    
                      
        
              - 
          
          
                      1000ms
            
          
                      Tried: 460
            Accepted: 194
            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