2022-02-20:设计内存文件系统。 设计一个内存文件系统,模拟以下功能: ls: 以字符串的格式输入一个路径。如果它是一个文件的路径,那么函数返回一个列表,仅包含这个文件的名字。如果它是一个文件夹的的路径,那么返回该 文件夹内 的所有文件和子文件夹的名字。你的返回结果(包括文件和子文件夹)应该按字典序排列。 mkdir:输入一个当前不存在的 文件夹路径 ,你需要根据路径名创建一个新的文件夹。如果有上层文件夹路径不存在,那么你也应该将它们全部创建。这个函数的返回类型为 void 。 addContentToFile: 输入字符串形式的 文件路径 和 文件内容 。如果文件不存在,你需要创建包含给定文件内容的文件。如果文件已经存在,那么你需要将给定的文件内容 追加 在原本内容的后面。这个函数的返回类型为 void 。 readContentFromFile: 输入 文件路径 ,以字符串形式返回该文件的 内容 。 力扣588。

答案2022-02-20:

路径字符串按/分割成多个字符串,组装成树形结构。然后根据自然智慧就能求解。

代码用golang编写。代码如下:

package main

import (
    "fmt"
    "strings"
)

func main() {
    fs := NewFileSystem()
    ret := make([]string, 0)

    ret = fs.ls("/")
    fmt.Println("ls = ", ret)

    fs.mkdir("/a/b/c")
    fs.addContentToFile("/a/b/c/d", "hello")

    ret = fs.ls("/")
    fmt.Println("ls = ", ret)

    c := fs.readContentFromFile("/a/b/c/d")
    fmt.Println("content = ", c)
}

type Node struct {
    // 文件名、目录名
    name string
    // content == null 意味着这个节点是目录
    // content != null 意味着这个节点是文件
    //public StringBuilder content;
    content string
    //public TreeMap<String, Node> nexts;
    nexts map[string]*Node
}

// 构造目录
func NewNode(n string) *Node {
    ret := &Node{}
    ret.name = n
    //ret.content = null;
    ret.nexts = make(map[string]*Node)
    return ret
}

// 构造文件,c是文件内容
func NewNode2(n, c string) *Node {
    ret := &Node{}
    ret.name = n
    //content = new StringBuilder(c);
    ret.content = c
    //nexts = new TreeMap<>();
    ret.nexts = make(map[string]*Node)
    return ret
}

type FileSystem struct {
    head *Node
}

func NewFileSystem() *FileSystem {
    ret := &FileSystem{}
    ret.head = NewNode("")
    return ret
}

func (this *FileSystem) ls(path0 string) []string {
    //List<String> ans = new ArrayList<>();
    ans := make([]string, 0)
    cur := this.head
    parts := strings.Split(path0, "/")
    n := len(parts)
    if path0 == "/" {
        n = 1
    }
    for i := 1; i < n; i++ {
        if _, ok := cur.nexts[parts[i]]; !ok {
            return ans
        }
        cur = cur.nexts[parts[i]]
    }
    // cur结束了!来到path最后的节点,该返回了
    // ls a/b/c  cur 来到c目录
    // 如果c是目录,那么就要返回c下面所有的东西!
    // 如果c是文件,那么就值返回c
    if cur.content == "" {
        //ans.addAll(cur.nexts.keySet());///
        for k, _ := range cur.nexts {
            ans = append(ans, k)
        }
        //fmt.Println("aaa")
    } else {
        //ans.add(cur.name);///
        ans = append(ans, cur.name)
        //fmt.Println("bbb")
    }

    return ans
}

func (this *FileSystem) mkdir(path0 string) {
    cur := this.head
    parts := strings.Split(path0, "/")
    n := len(parts)
    for i := 1; i < n; i++ {
        if _, ok := cur.nexts[parts[i]]; !ok {
            cur.nexts[parts[i]] = NewNode(parts[i])
        }
        cur = cur.nexts[parts[i]]
    }

}

func (this *FileSystem) addContentToFile(path0, content string) {
    cur := this.head
    parts := strings.Split(path0, "/")
    n := len(parts)
    for i := 1; i < n; i++ {
        if _, ok := cur.nexts[parts[i]]; !ok {
            cur.nexts[parts[i]] = NewNode(parts[i])
        }
        cur = cur.nexts[parts[i]]

    }
    // 来到的是倒数第二的节点了!注意for!
    if _, ok := cur.nexts[parts[n-1]]; !ok {
        cur.nexts[parts[n-1]] = NewNode2(parts[n-1], "")
    }
    cur.content += content
}

func (this *FileSystem) readContentFromFile(path0 string) string {
    cur := this.head
    parts := strings.Split(path0, "/")
    n := len(parts)
    for i := 1; i < n; i++ {
        if _, ok := cur.nexts[parts[i]]; !ok {
            cur.nexts[parts[i]] = NewNode(parts[i])
        }
        cur = cur.nexts[parts[i]]
    }
    return cur.content
}

执行结果如下: 图片


左神java代码