目录

题目

思路

Code


题目

构建一个虚拟文件系统,此文件系统须提供如下两种功能:
添加文件(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 = 文件。

  1. addfile:按 / 拆分路径,前面的部分逐级建文件夹(字典),最后一个部分存为文件(None)
  2. 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。让他帮助你查询原因。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐