588. Design In-Memory File System

588. Design In-Memory File System

Description

Design a data structure that simulates an in-memory file system.

Implement the FileSystem class:

  • FileSystem() Initializes the object of the system.

  • List<String> ls(String path)

  • If path is a file path, returns a list that only contains this file’s name.

  • If path is a directory path, returns the list of file and directory names in this directory .

The answer should in lexicographic order .

  • void mkdir(String path) Makes a new directory according to the given path. The given directory path does not exist. If the middle directories in the path do not exist, you should create them as well.

  • void addContentToFile(String filePath, String content)

  • If filePath does not exist, creates that file containing given content.

  • If filePath already exists, appends the given content to original content.

  • String readContentFromFile(String filePath) Returns the content in the file at filePath.

Example 1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Input

["FileSystem", "ls", "mkdir", "addContentToFile", "ls", "readContentFromFile"]
[[], ["/"], ["/a/b/c"], ["/a/b/c/d", "hello"], ["/"], ["/a/b/c/d"]]
Output

[null, [], null, null, ["a"], "hello"]

Explanation

FileSystem fileSystem = new FileSystem();
fileSystem.ls("/"); // return []
fileSystem.mkdir("/a/b/c");
fileSystem.addContentToFile("/a/b/c/d", "hello");
fileSystem.ls("/"); // return ["a"]
fileSystem.readContentFromFile("/a/b/c/d"); // return "hello"

Constraints:

  • 1 <= path.length,filePath.length <= 100
  • path and filePathare absolute paths which begin with '/'and do not end with '/'except that the path is just"/".
  • You can assume that all directory names and file names only contain lowercase letters, and the same names will not exist in the same directory.
  • You can assume that all operations will be passed valid parameters, and users will not attempt to retrieve file content or list a directory or file that does not exist.
  • You can assume that the parent directory for the file in addContentToFile will exist.
  • 1 <= content.length <= 50
  • At most 300 calls will be made to ls, mkdir,addContentToFile, andreadContentFromFile.

Hints/Notes

Solution

Language: C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
class FileSystem {
public:
struct Object {
Object(string name) {
this->name = name;
isFile = false;
}
unordered_map<string, Object*> children;
bool isFile = false;
string name;
string fileContent;
};

Object* root;

FileSystem() {
root = new Object("root");
}

vector<string> ls(string path) {
vector<string> names = parsePath(path);
Object* curNode = root;
for (auto& name : names) {
curNode = curNode->children[name];
}
set<string> res;
if (curNode->isFile) {
res.insert(curNode->name);
} else {
for (auto [k, _] : curNode->children) {
res.insert(k);
}
}
return vector<string>(res.begin(), res.end());
}

void mkdir(string path) {
vector<string> names = parsePath(path);
Object* curNode = root;
for (auto& name : names) {
if (!curNode->children.contains(name)) {
curNode->children[name] = new Object(name);
}
curNode = curNode->children[name];
}
}

void addContentToFile(string filePath, string content) {
vector<string> names = parsePath(filePath);
Object* curNode = root;
for (auto& name : names) {
if (!curNode->children.contains(name)) {
curNode->children[name] = new Object(name);
}
curNode = curNode->children[name];
}
curNode->isFile = true;
curNode->fileContent += content;
}

string readContentFromFile(string filePath) {
vector<string> names = parsePath(filePath);
Object* curNode = root;
for (auto& name : names) {
if (!curNode->children.contains(name)) {
curNode->children[name] = new Object("name");
}
curNode = curNode->children[name];
}
return curNode->fileContent;
}

vector<string> parsePath(string& filePath) {
vector<string> names;
int start = 1, end;
while ((end = filePath.find('/', start)) != string::npos) {
names.push_back(filePath.substr(start, end - start));
start = end + 1;
}
if (start < filePath.size()) {
names.push_back(filePath.substr(start));
}
return names;
}
};

/**
* Your FileSystem object will be instantiated and called as such:
* FileSystem* obj = new FileSystem();
* vector<string> param_1 = obj->ls(path);
* obj->mkdir(path);
* obj->addContentToFile(filePath,content);
* string param_4 = obj->readContentFromFile(filePath);
*/