华为OD机试双机位C卷-虚拟文件系统(C/C++/Py/Java/Js/Go)

虚拟文件系统

华为OD机试双机位C卷 - 华为OD上机考试双机位C卷 100分题型

华为OD机试双机位C卷真题目录点击查看: 华为OD机试双机位C卷真题题库目录|机考题库 + 算法考点详解

题目描述

构建一个虚拟文件系统,此文件系统须提供如下两种功能:

  • 添加文件(addfile命令)
  • 展示文件夹内容(ls)

其中通过addfile命令可以添加文件到指定目录,例如addfile /src/main/java/x.java。通过ls命令可以输出本目录下所有文件夹和文件命令,例如ls /src输出x.java,ls /src/main/java输出x.java,其中星号用于标识文件夹,而非末端文件。

输入描述

每行输入一个添加文件的指令,包括addfile 固定前缀和/开头的文件路径。

最后一行输入一个展示目录内容指令,包括ls 固定前缀和/开头的文件夹路径名

输出描述

用两个空格分割文件夹/文件,输出本目录下所有文件夹/文件即可,按照文件夹/文件的字符串字典序排序输出。

用例1

输入

none 复制代码
addfile /src/main/java/democlass.java
addfile /src/main/java/demoentity.java
addfile /src/main/java/com/demo/it/demoservice.class
addfile /src/main/resource/application.yml
addfile /src/main/resource/log.yml
ls /src

输出

none 复制代码
main*

用例2

输入

none 复制代码
addfile /src/main/java/democlass.java
addfile /src/main/java/demoentity.java
addfile /src/main/java/com/demo/it/demoservice.class
addfile /src/main/resource/application.yml
addfile /src/main/resource/log.yml
ls /src/main/java

输出

none 复制代码
com* democlass.java demoentity.java

题解

思路:模拟

  1. 利用输入的添加文件命令,构建出对应的文件树结构(借助类/结构体)来实现。
  2. 对于添加文件命令的解析,分割出具体路径然后进行解析,如果对应目录或文件不存在则创建。此时可以注意一个特殊情况/a/b/a/b/c.txt这两个文件目录,需要将目录和文件进行区分,这里结合题目要输出的目录可以人为在文件夹名后添加一个*以达到区分。
  3. ls 文件夹解析逻辑和创建文件差不多,找到对应目录后将该目录下的文件/文件夹添加到结果数组。排序之后进行输出即可。

C++

c++ 复制代码
#include<iostream>
#include<vector>
#include<string>
#include <utility> 
#include <sstream>
#include<algorithm> 
#include<cmath>
#include<map>
using namespace std;

struct Node {
    map<string, Node*> children; 
    bool isFile;
    Node() {
        isFile = false;
    }
};

// 根目录
Node* root = new Node();


// 通用 切割函数 函数 将字符串str根据delimiter进行切割
vector<string> split(const string& str, const string& delimiter) {
    vector<string> result;
    size_t start = 0;
    size_t end = str.find(delimiter);
    while (end != string::npos) {
        result.push_back(str.substr(start, end - start));
        start = end + delimiter.length();
        end = str.find(delimiter, start);
    }
    // 添加最后一个部分
    result.push_back(str.substr(start));
    return result;
}

// 添加文件
void addFile(const string& cmd) {
    // 切割获取文件目录
    string filePath = split(cmd, " ")[1];
    
    vector<string> parts = split(filePath, "/");
    Node* cur = root;
    for (int i = 0; i < parts.size(); i++) {
        string name = parts[i];
        if (name.empty()) {
            continue;
        }
        bool isFile = false;
        // 最后一个是文件
        if (i == parts.size() - 1) {
            isFile = true;
        }
        if (!isFile) {
            name += "*";
        }

        if (!cur->children.count(name)) {
            cur->children[name] = new Node();
        }
        cur = cur->children[name];
        cur->isFile = isFile;
    }
}

// ls 命令
void ls(const string& cmd, vector<string>& res) {
    string path = split(cmd, " ")[1];
    Node* cur = root;

    vector<string> parts = split(path, "/");

    // 找到目录
    for (int i = 0; i < parts.size(); i++) {
        string name = parts[i];
        if (name.empty()) {
            continue;
        }
        name += "*";
        if (!cur->children.count(name)) return;
        cur = cur->children[name];
    }

    bool first = true;


    for (auto& [name, node] : cur->children) {
        res.push_back(name);
    }
}




int main() {
    vector<string> inputs;
    string line;
    // 读取所有输入
    while (getline(cin, line)) {
        inputs.push_back(line);
    }

    // 最后一行是 ls
    int n = inputs.size();

    for (int i = 0; i < n - 1; i++) {
        string cmd = inputs[i];
        addFile(cmd);
    }
    string lsCmd = inputs[n - 1];
    vector<string> res;
    ls(lsCmd, res);

    sort(res.begin(), res.end());
    int m = res.size();
    //输出结果
    for (int i = 0; i < m; i++) {
        cout << res[i];
        if (i !=  m -1) {
            cout << "  ";
        }
    }
    return 0;
}

JAVA

JAVA 复制代码
import java.util.*;

public class Main {
    static class Node {
        Map<String, Node> children = new HashMap<>();
        boolean isFile = false;
    }

    static Node root = new Node();

    // 添加文件
    static void addFile(String cmd) {
        String filePath = cmd.split(" ")[1];
        String[] parts = filePath.split("/");

        Node cur = root;
        for (int i = 0; i < parts.length; i++) {
            String name = parts[i];
            if (name.isEmpty()) continue;
            boolean isFile = i == parts.length - 1;

            if (!isFile) name += "*";

            cur.children.putIfAbsent(name, new Node());
            cur = cur.children.get(name);
            cur.isFile = isFile;
        }
    }

    // ls 命令
    static void ls(String cmd, List<String> res) {
        String path = cmd.split(" ")[1];
        String[] parts = path.split("/");

        Node cur = root;
        for (String name : parts) {
            if (name.isEmpty()) continue;
            name += "*";
            if (!cur.children.containsKey(name)) return;
            cur = cur.children.get(name);
        }

        for (String name : cur.children.keySet()) {
            res.add(name);
        }
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        List<String> inputs = new ArrayList<>();
        while (sc.hasNextLine()) {
            inputs.add(sc.nextLine());
        }
        int n = inputs.size();
        for (int i = 0; i < n - 1; i++) addFile(inputs.get(i));
        String lsCmd = inputs.get(n - 1);

        List<String> res = new ArrayList<>();
        ls(lsCmd, res);
        Collections.sort(res);

        for (int i = 0; i < res.size(); i++) {
            System.out.print(res.get(i));
            if (i != res.size() - 1) System.out.print("  ");
        }
    }
}

Python

python 复制代码
import sys

class Node:
    def __init__(self):
        self.children = {}
        self.isFile = False

root = Node()

def addFile(cmd):
    filePath = cmd.split(" ")[1]
    parts = filePath.split("/")
    cur = root
    for i, name in enumerate(parts):
        if not name:
            continue
        isFile = i == len(parts) - 1
        if not isFile:
            name += "*"
        if name not in cur.children:
            cur.children[name] = Node()
        cur = cur.children[name]
        cur.isFile = isFile

def ls(cmd):
    path = cmd.split(" ")[1]
    parts = path.split("/")
    cur = root
    for name in parts:
        if not name:
            continue
        name += "*"
        if name not in cur.children:
            return []
        cur = cur.children[name]
    return list(cur.children.keys())

# 读取输入
inputs = [line.strip() for line in sys.stdin if line.strip()]
for cmd in inputs[:-1]:
    addFile(cmd)

res = ls(inputs[-1])
res.sort()
print("  ".join(res))

JavaScript

js 复制代码
const readline = require('readline');

class Node {
    constructor() {
        this.children = {};
        this.isFile = false;
    }
}

let root = new Node();

// 创建文件命令
function addFile(cmd) {
    let filePath = cmd.split(" ")[1];
    let parts = filePath.split("/");
    let cur = root;
    for (let i = 0; i < parts.length; i++) {
        let name = parts[i];
        if (!name) continue;
        let isFile = i === parts.length - 1;
        if (!isFile) name += "*";
        if (!(name in cur.children)) cur.children[name] = new Node();
        cur = cur.children[name];
        cur.isFile = isFile;
    }
}

// ls命令
function ls(cmd) {
    let path = cmd.split(" ")[1];
    let parts = path.split("/");
    let cur = root;
    for (let name of parts) {
        if (!name) continue;
        name += "*";
        if (!(name in cur.children)) return [];
        cur = cur.children[name];
    }
    return Object.keys(cur.children);
}

const rl = readline.createInterface({
    input: process.stdin
});

let inputs = [];

rl.on('line', (line) => {
    inputs.push(line.trim());
}).on('close', () => {
    for (let i = 0; i < inputs.length - 1; i++) addFile(inputs[i]);
    let res = ls(inputs[inputs.length - 1]);
    res.sort();
    console.log(res.join("  "));
});

Go

go 复制代码
package main

import (
    "bufio"
    "fmt"
    "os"
    "sort"
    "strings"
)

type Node struct {
    children map[string]*Node
    isFile   bool
}

var root = &Node{children: make(map[string]*Node)}

// 创建文件
func addFile(cmd string) {
    parts := strings.Split(cmd, " ")[1]
    path := strings.Split(parts, "/")
    cur := root
    for i, name := range path {
        if name == "" {
            continue
        }
        isFile := i == len(path)-1
        if !isFile {
            name += "*"
        }
        if _, ok := cur.children[name]; !ok {
            cur.children[name] = &Node{children: make(map[string]*Node)}
        }
        cur = cur.children[name]
        cur.isFile = isFile
    }
}

// ls命令
func ls(cmd string) []string {
    parts := strings.Split(cmd, " ")[1]
    path := strings.Split(parts, "/")
    cur := root
    for _, name := range path {
        if name == "" {
            continue
        }
        name += "*"
        next, ok := cur.children[name]
        if !ok {
            return []string{}
        }
        cur = next
    }
    res := []string{}
    for k := range cur.children {
        res = append(res, k)
    }
    return res
}

func main() {
    scanner := bufio.NewScanner(os.Stdin)
    inputs := []string{}
    for scanner.Scan() {
        line := scanner.Text()
        if strings.TrimSpace(line) != "" {
            inputs = append(inputs, line)
        }
    }

    for i := 0; i < len(inputs)-1; i++ {
        addFile(inputs[i])
    }

    res := ls(inputs[len(inputs)-1])
    // 升序排序
    sort.Strings(res)
    fmt.Print(strings.Join(res, "  "))
}

C语言

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Node {
    char *name;           // 文件/文件夹名字
    int isFile;           // 是否是文件
    struct Node **children; // 子节点数组
    int childCount;       // 子节点数量
    int childCap;         // 子节点容量
} Node;

// 根目录
Node *root;

// 创建节点
Node* createNode(const char *name, int isFile) {
    Node *node = (Node*)malloc(sizeof(Node));
    node->name = malloc(strlen(name) + 1);
    strcpy(node->name, name);
    node->isFile = isFile;
    node->childCount = 0;
    node->childCap = 4;
    node->children = malloc(sizeof(Node*) * node->childCap);
    return node;
}

// 查找子节点
Node* findChild(Node *parent, const char *name) {
    for (int i = 0; i < parent->childCount; i++) {
        if (strcmp(parent->children[i]->name, name) == 0)
            return parent->children[i];
    }
    return NULL;
}

// 添加文件
void addFile(char *cmd) {
    char *filePath = cmd + 8; // 跳过 "addfile "
    Node *cur = root;
    char path[512];
    strcpy(path, filePath);

    char *token = strtok(path, "/");
    while (token) {
        char name[512];
        int isFile = 0;
        token[strcspn(token, "\n")] = 0;
        char *next = strtok(NULL, "/");
        if (!next) isFile = 1;  // 最后一个是文件
        if (!isFile) sprintf(name, "%s*", token);
        else strcpy(name, token);

        Node *child = findChild(cur, name);
        if (!child) {
            child = createNode(name, isFile);
            if (cur->childCount == cur->childCap) {
                cur->childCap *= 2;
                cur->children = realloc(cur->children, sizeof(Node*) * cur->childCap);
            }
            cur->children[cur->childCount++] = child;
        }
        cur = child;
        token = next;
    }
}

// qsort 比较函数
int cmp(const void *a, const void *b) {
    Node *na = *(Node**)a;
    Node *nb = *(Node**)b;
    return strcmp(na->name, nb->name);
}

// ls 命令
void ls(char *cmd) {
    char *path = cmd + 3; // 跳过 "ls "
    Node *cur = root;
    char p[512];
    strcpy(p, path);
    char *token = strtok(p, "/");
    while (token) {
        token[strcspn(token, "\n")] = 0;
        if (strlen(token) == 0) {
            token = strtok(NULL, "/");
            continue;
        }
        char name[512];
        sprintf(name, "%s*", token);
        Node *child = findChild(cur, name);
        if (!child) return; // 目录不存在
        cur = child;
        token = strtok(NULL, "/");
    }

    // 排序输出
    qsort(cur->children, cur->childCount, sizeof(Node*), cmp);
    for (int i = 0; i < cur->childCount; i++) {
        printf("%s", cur->children[i]->name);
        if (i != cur->childCount - 1) printf("  ");
    }
}

int main() {
    root = createNode("/", 0);

    char line[512];
    char *inputs[1000];
    int inputCount = 0;

    // 读取所有输入
    while (fgets(line, sizeof(line), stdin)) {
        line[strcspn(line, "\n")] = 0;
        inputs[inputCount] = malloc(strlen(line) + 1);
        strcpy(inputs[inputCount++], line);
    }

    // 最后一行是 ls
    for (int i = 0; i < inputCount - 1; i++) {
        addFile(inputs[i]);
    }
    ls(inputs[inputCount - 1]);

    return 0;
}
相关推荐
sprite_雪碧2 天前
考研机试笔记-1输入输出
笔记·考研·华为od
无限码力6 天前
华为OD机试真题2026双机位C卷 C++实现【日志解析】
c++·华为od·华为od机试真题·华为od机考真题·华为od机试真题-日志解析
uesowys9 天前
华为OD算法开发指导-数据结构-图
数据结构·算法·华为od
快敲啊死鬼12 天前
机试day5
算法·华为od·华为
LqKKsNUdXlA1 个月前
Comsol冻土水热力耦合模型代做 可复现白青波,秦晓同模型 建立了路基水热耦合计算控制方程
华为od
开开心心_Every1 个月前
剪切板工具存500条,可搜索备份导入导出
linux·运维·服务器·华为od·edge·pdf·华为云
开开心心_Every1 个月前
在线看报软件, 22家知名报刊免费看
linux·运维·服务器·华为od·edge·pdf·华为云
uesowys1 个月前
华为OD算法开发指导-二级索引-Read and Write Path Different Version
java·算法·华为od
西电研梦2 个月前
26西电考研 | 寒假开始,机试 or C语言程序设计怎么准备?
c语言·考研·华为od·研究生·西安电子科技大学·计算机408