【CCFCSP】201604-3 路径解析

时间:2022-10-13 21:35:31

试题编号: 201604-3
试题名称: 路径解析
时间限制: 1.0s
内存限制: 256.0MB

//参考了别人的博客

本题主要考察对字符串的修改操作。可以用string保存路径信息,再使用string的类函数进行操作。
首先读入当前目录,要注意在之后的P行路径中的相对路径表示的是相对初始当前目录的路径,而不是上一次的结果目录。如果读入的是相对路径,可以直接把初始目录和相对路径拼接后的路径当做需要正规化的路径。
然后对路径修改。字符串中子串或字符的删除可以直接用erase函数实现。首先删除字符串中重复的“/”。然后考虑”//”形式,这个符号不会对之前和之后的路径产生影响,所以直接删除。再考虑”/*/”形式,代表回到上一目录,所以处理时删除这一段以及上一段的目录,(如果在它之前是根目录,只需删除这一段)。如果最后的目录不是根目录,且结尾带有”/”,则需要进行删除。

#include <iostream>
#include <string>
using namespace std;
int main() {
    int P;
    string cur,s;//cur保存当前目录,s保存之后每个需要正规化的路径
    cin >> P >> cur;
    cin.ignore();//防止读入换行符
    for (int i = 0; i < P; i++) {
        string s;
        getline(cin, s);
        int p;//用作指针
        if (s[0] != '/') {
            //相对路径的处理
            s = cur + "/" + s;
        }
        if (s.size() == 0) {
            //注意考虑输入为空行的情况
            s = cur;
        }
        //删除多余的"/"
        while ((p = s.find("//")) != -1) {
            int count = 2;
            while (s[p + count] == '/') {
                count++;
            }
            s.erase(p, count - 1);
        }
        //删除"/*/"
        while ((p = s.find("/./")) != -1) {
            s.erase(p + 1, 2);
        }
        //处理"/**/"
        while ((p = s.find("/../")) != -1) {
            if (p == 0) {
                s.erase(p + 1, 3);
            }
            else {
                //使用rfind向前查找
                int p1 = s.rfind("/", p - 1);
                s.erase(p1, p - p1 + 3);
            }
        }
        //删除末尾的"/"
        if(s.length() > 1 && s[s.length()-1] == '/')
            s.erase(s.length() - 1);
        cout << s << endl;
    }
    return 0;
}