文件系统

solve actually problem!

请根据下面操作实现一个文件系统,具体操作如下:

FileSystem() 初始化过程,当前目录在根目录/,根目录下为空。

MakeDir(string dirName) 在当前目录下创建一个新的目录,若目录名与当前目录下的文件名或目录重复,则创建失败,返回false;否则创建成功,返回true。

MakeFile(string fileName) 在当前目录下创建一个新的文件,若文件名fileName和当前目录下的文件名和目录名重复,则创建失败,返回false;否则创建成功,返回true。

ChangeDir(string pathName) 切换当前目录到pathName

  • pathName"",当前目录保持不变,返回true;

  • 若目录存在则切换成功,并返回true;否则直接返回false;

    pathName可能是绝对路径/xx/yy/zz,也可能是相对路径xx/yy/zz

Remove(string name) 删除当前目录下名称为name的文件或者目录。

  • 若存在则删除成功,并返回true;否则,直接返回false
  • 删除目录时,需要联动删除该目录下的所有子目录和文件。
  • ListDir() 返回当前目录下的目录和文件,目录在前文件在后,各自按字典序升序(不包含子目录下的内容)。

输入要求

每行表示一个函数调用,初始化函数仅仅首行调用一次,累计函数调用不超过1000次。flieNamedirNamename仅含小写字母,长度范围皆为[1, 100],pathName仅含小写字母和/,0 <= pathName.length < 1000;不包括..或者.

输出要求

答题时按照函数/方法原型中的要求(含返回值)进行实现

样例如下:

输入

FileSystem()
MakeDir("dirc")
MakeDir("dirb")
MakeDir("dirc")
ListDir()
ChangeDir("dirc/")
CreateFile("fileb")
MakeDir("dirb")
CreateFile("dirb")
ListDir()
ChangeDir("/dirb/dirc")

输出

null
true
true
false
["dirb", "dirc"]
true
true
true
false
["dirb", "fileb"]
false

具体实现

#include <bits/stdc++.h>

using namespace std;

class FileSystem {
public:
    FileSystem()
    {
        mp["/"] = {};
        curPath = "/";
    }

    bool MakeDir(const string &dirName)
    {
        if (mp[curPath].count({curPath + dirName, "dir"}) ||
            mp[curPath].count({curPath + dirName, "file"})) {
            return false;
        }
        mp[curPath].insert({curPath + dirName, "dir"});
        return true;
    }

    bool MakeFile(const string &fileName)
    {
        if (mp[curPath].count({curPath + fileName, "dir"}) ||
            mp[curPath].count({curPath + fileName, "file"})) {
            return false;
        }
        mp[curPath].insert({curPath + fileName, "file"});
        return true;
    }

    bool ChangeDir(const string &pathName)
    {
        if (pathName.empty()) {
            return true;
        }

        string path;
        if (pathName[0] != '/') {
            path = curPath + pathName;
        } else {
            path = pathName;
        }

        if (path[path.size() - 1] == '/') {
            path = path.substr(0, path.size() - 1);
        }

        if (!any_of(mp.begin(), mp.end(), [&](auto x) {
            return x.second.count({path, "dir"}) != 0;
        }) && !path.empty()) {
            return false;
        }

        curPath = path + "/";
        return true;
    }

    bool Remove(const string &name)
    {
        auto pName_ = curPath + name;
        if (mp[curPath].count({pName_, "dir"}) != 0) {
            return RecursiveRemove(pName_, curPath);
        }
        
        if (mp[curPath].count({pName_, "file"}) != 0) {
            mp[curPath].erase({pName_, "file"});
            return true;
        }
        return false;
    }

    void RecursiveRemove(const string &pName, const string &cPath)
    {
        if (!mp[pName].empty()) {
            return false;
        }

        for (const auto &x : mp[pName]) {
            if (x.second == "file") {
                mp[pName].erase(x);
                continue;
            }
            return RecursiveRemove(x.first, pName);
        }
        mp[cPath].erase({pName, "dir"});
        return true;
    }
    
    vector<string> ListDir()
    {
        int len = curPath.size();
        vector<pair<string, string>> res(mp[curPath].begin(), mp[curPath].end());
        sort(res.begin(), res.end(), [](auto a, auto b) {
            if (a.second != b.second) {
                return a.second < b.second;
            } else {
                return a.first < b.first;
            }
        });

        vector<string> ans;
        for (const auto &x : res) {
            ans.push_back(x.first.substr(len));
        }
        return ans;
    }

private:
    map<string, set<pair<string, string>>> mp;
    string curPath;
};