C++ Solution


  • 0
    class FileSystem {
    public:
        FileSystem() : root("", false) { }
    
        vector<string> ls(string path) {
            vector<string> filenames;
            vector<string> toks = split(path);
            File* file = getFile(path);
            if (file) {
                if (file->isFile()) {
                    filenames.push_back(file->getName());
                }
                else {
                    vector<File*> files = file->getChildren();
                    for (File* file : files) {
                        filenames.push_back(file->getName());
                    }
                }
            }
            return filenames;
        }
    
        void mkdir(string path) {
            File* file = getFile(path);
            if (file && file->isFile()) {
                throw logic_error("Cannot create directory on existing file.");
            }
    
            if (!file) {
                vector<string> toks = split(path);
                File* file = &root;
                for (int i = 0; i < toks.size() && file && !file->isFile(); i++) {
                    if (toks[i].empty()) {
                        continue;
                    }
                    if (!file->getChild(toks[i])) {
                        file->add(toks[i], false);
                    }
                    file = file->getChild(toks[i]);
                }
            }
        }
    
        void addContentToFile(string filePath, string content) {
            File* file = getFile(filePath);
            if (!file) {
                int lastdiv = filePath.find_last_of('/');
                string dirpath = filePath.substr(0, lastdiv);
                string filename = filePath.substr(lastdiv + 1);
                mkdir(dirpath);
                File* dir = getFile(dirpath);
                dir->add(filename, true);
                file = getFile(filePath);
            }
            file->append(content);
        }
    
        string readContentFromFile(string filePath) {
            File* file = getFile(filePath);
            if (!file || !file->isFile()) {
                return "";
            }
            return file->getContent();
        }
    
        class File;
        File* getRoot() {
            return &root;
        }
    
    public:
        class File {
        public:
            File() : name(""), file(false) {};  // the default constructor is used by the map [] operator
            File(string name, bool file) : name(name), file(file) { }
    
            bool isFile() {
                return file;
            }
    
            void append(string content) {
                if (!file) throw logic_error("Not a file");
                this->content.append(content);
            }
    
            string getContent() {
                if (!file) throw logic_error("Not a file");
                return this->content;
            }
    
            vector<File*> getChildren() {
                if (file) throw logic_error("Not a directory");
    
                vector<File*> files;
                for (auto it = children.begin(); it != children.end(); it++) {
                    files.push_back(&it->second);
                }
                return files;
            }
    
            File* getChild(string name) {
                return children.count(name) ? &children[name] : nullptr;
            }
    
            void add(string name, bool file) {
                children[name] = File(name, file);
            }
    
            string getName() {
                return name;
            }
    
        private:
            string name;
            bool file = true;
            string content;
            map<string, File> children;
        };
    
    private:
        File root;
    
        vector<string> split(string path) {
            vector<string> toks;
            int i = 0, j = string::npos;
            while ((j = path.find('/', i)) != string::npos) {
                toks.push_back(path.substr(i, j - i));
                i = j + 1;
            }
    
            if (i < path.size()) {
                toks.push_back(path.substr(i));
            }
            return toks;
        }
    
        File* getFile(string path) {
            vector<string> toks = split(path);
            File* file = &root;
            for (int i = 0; i < toks.size() && file && !file->isFile(); i++) {
                if (toks[i].empty()) {
                    continue;
                }
                file = file->getChild(toks[i]);
            }
    
            return file;
        }
    };
    
    /**
    * 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);
    */
    

Log in to reply
 

Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.