华为OD机试真题2026双机位C卷 Java&Go 实现【虚拟文件系统】
目录
题目
构建一个虚拟文件系统,此文件系统须提供如下两种功能:
添加文件(addfile命令)
展示文件夹内容(ls命令)
其中通过addfile命令可以添加文件到指定目录,例如 addfile /src/main/java/x.java。通过Is命令可以输出本目录下所有文件夹和文件命令,例如ls /src 输出main*,ls /src/main/java输出x.java,其中星号用于标识文件夹,而非末端文件。
输入描述
每行输入一个添加文件的指令,包括addfile固定前缀和/开头的文件路径。
最后一行输入一个展示目录内容指令,包括Is固定前缀和/开头的文件夹路径名
输出描述
用两个空格分割文件夹/文件,输出本目录下所有文件夹/文件即可,按照文件夹/文件的字符串字典序排序输出。示例1
输入:
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*
示例2
输入:
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
输出:
com* democlass.java demoentity.java
思路
逻辑模拟类的题目,直接按照题意,用嵌套字典当目录树:
dict= 文件夹,None= 文件。
- addfile:按
/拆分路径,前面的部分逐级建文件夹(字典),最后一个部分存为文件(None)- ls:沿路径找到目标节点,遍历其子项——是字典的加
*,否则直接取名——排序后输出
Code
import java.util.*;
public class Main {
public static void main(String[] args) {
Map<String, Object> root = new HashMap<>(); // 根节点,嵌套Map模拟文件系统树
Scanner sc = new Scanner(System.in);
List<String> lines = new ArrayList<>();
while (sc.hasNextLine()) {
String line = sc.nextLine().trim();
if (!line.isEmpty()) lines.add(line);
}
String lsPath = null;
for (String line : lines) {
if (line.startsWith("addfile ")) {
String path = line.substring(8); // 去掉 "addfile " 前缀,拿到文件路径
String trimmed = path.replaceAll("^/+|/+$", "");
String[] parts = trimmed.split("/"); // 按 / 拆分成各级目录和文件名
Map<String, Object> node = root;
// 沿路径逐级创建文件夹(中间部分都是文件夹)
for (int i = 0; i < parts.length - 1; i++) {
if (!node.containsKey(parts[i])) {
node.put(parts[i], new HashMap<String, Object>()); // 不存在则新建Map表示文件夹
}
node = (Map<String, Object>) node.get(parts[i]); // 进入下一级
}
node.put(parts[parts.length - 1], null); // 路径最后一段是文件,用 null 标记
} else if (line.startsWith("ls ")) {
lsPath = line.substring(3); // 去掉 "ls " 前缀,拿到要查看的目录路径
}
}
if (lsPath == null) return;
// 处理 ls 路径:trim 后为空说明是根目录,直接用 root
String stripped = lsPath.replaceAll("^/+|/+$", "");
Map<String, Object> node = root;
if (!stripped.isEmpty()) {
// 沿 ls 路径找到目标文件夹节点
String[] parts = stripped.split("/");
for (String p : parts) {
if (!node.containsKey(p) || !(node.get(p) instanceof Map)) {
System.out.println(""); // 路径不存在或不是文件夹,输出空
return;
}
node = (Map<String, Object>) node.get(p);
}
}
// 遍历目标文件夹的直接子项
List<String> items = new ArrayList<>();
for (Map.Entry<String, Object> entry : node.entrySet()) {
if (entry.getValue() instanceof Map) {
items.add(entry.getKey() + "*"); // 子项是Map → 文件夹,加 * 标记
} else {
items.add(entry.getKey()); // 子项是 null → 文件,直接用文件名
}
}
Collections.sort(items); // 按字典序排序
System.out.println(String.join(" ", items)); // 用两个空格分隔输出
}
}
Go
package main
import (
"bufio"
"fmt"
"os"
"sort"
"strings"
)
type Node struct {
children map[string]*Node // 子文件夹
files map[string]bool // 子文件
}
// 创建一个新节点
func newNode() *Node {
return &Node{children: make(map[string]*Node), files: make(map[string]bool)}
}
// 按 / 拆分路径,去掉首尾空串
func splitPath(path string) []string {
parts := strings.Split(strings.Trim(path, "/"), "/")
var result []string
for _, p := range parts {
if p != "" {
result = append(result, p)
}
}
return result
}
func main() {
root := newNode() // 根节点,树结构模拟文件系统
scanner := bufio.NewScanner(os.Stdin)
var lines []string
for scanner.Scan() {
lines = append(lines, scanner.Text())
}
lsPath := ""
hasLs := false
for _, line := range lines {
if strings.HasPrefix(line, "addfile ") {
path := line[8:] // 去掉 "addfile " 前缀,拿到文件路径
parts := splitPath(path) // 按 / 拆分成各级目录和文件名
node := root
// 沿路径逐级创建文件夹(中间部分都是文件夹)
for i := 0; i < len(parts)-1; i++ {
if _, ok := node.children[parts[i]]; !ok {
node.children[parts[i]] = newNode() // 不存在则新建节点表示文件夹
}
node = node.children[parts[i]] // 进入下一级
}
node.files[parts[len(parts)-1]] = true // 路径最后一段是文件
} else if strings.HasPrefix(line, "ls ") {
lsPath = line[3:] // 去掉 "ls " 前缀,拿到要查看的目录路径
hasLs = true
}
}
if !hasLs {
return
}
// 处理 ls 路径:拆分后为空说明是根目录,直接用 root
parts := splitPath(lsPath)
node := root
valid := true
for _, p := range parts {
child, ok := node.children[p]
if !ok {
valid = false // 路径不存在
break
}
node = child
}
if !valid {
fmt.Println("")
return
}
// 遍历目标文件夹的直接子项
var items []string
for name := range node.children {
items = append(items, name+"*") // 子文件夹,加 * 标记
}
for name := range node.files {
items = append(items, name) // 文件,直接用文件名
}
sort.Strings(items) // 按字典序排序
fmt.Println(strings.Join(items, " ")) // 用两个空格分隔输出
}
【华为od机试真题Python+JS+Java+Go合集】【超值优惠】:Py/JS/Java/Go合集
【华为od机试真题Python】:Python真题题库
【华为od机试真题JavaScript】:JavaScript真题题库
【华为od机试真题Java&Go】:Java&Go真题题库
【华为od机试真题C++】:C++真题题库
【华为od机试真题C语言】:C语言真题题库
【华为od面试手撕代码题库】:面试手撕代码题库
【华为od机试面试交流群:830285880】【文章底部有二维码链接,可扫码加交流群】
华为OD机试:二本院校有机会吗?
有机会,但不大,大神除外!机考分数越高越好,所以需要提前刷题。机考通过后,如果没有收到面试邀请,也不要着急,非目标院校面试邀请发的时间比较晚。非目标院校今年有点难,机试至少要考到350分,所以需要疯狂刷题,华为OD机考是有题库的,最好在考前完所有题库题目。华为OD机试:跨专业可以参加华为OD可以,但是如果你的本科院校比较差,上岸概率不大。华为OD机试:华为OD简历被锁定机试通过,性格测试也通过,但是没人联系面试,发现简历被锁定。此时需要主动去联系HR。让他帮助你查询原因。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐




所有评论(0)