简易内存池2 - 华为OD统一考试(C卷)

news2024/11/14 19:01:32

OD统一考试(C卷)

分值: 200分

题解: Java / Python / C++

alt

题目描述

请实现一个简易内存池,根据请求命令完成内存分配和释放。

内存池支持两种操作命令,REQUEST和RELEASE,其格式为:

  • REQUEST=请求的内存大小 表示请求分配指定大小内存,如果分配成功,返回分配到的内存首地址;如果内存不足,或指定的大小为0,则输error。
  • RELEASE=释放的内存首地址 表示释放掉之前分配的内存,释放成功无需输出,如果释放不存在的首地址则输出error。

注意:

1.内存池总大小为100字节

2.内存池地址分配必须是连续内存,并优先从低地址分配

3.内存释放后可被再次分配,已释放的内存在空闲时不能被二次释放。

4.不会释放已电请的内存块的中间地排

5.释放操作只是针对首地址所对应的单个内存块进行操作,不会影响其它内存块。

输入描述

首行为整数N表示操作命令的个数,取值范围: 0 N<100。

接下来的N行,每行将给出一个操作命令,操作命令和参数之间用“=”分割。

输出描述

见题面输出要求

示例1

输入:
3
REQUEST=30
RELEASE=0
REQUEST=30

输出:
0
0

题解

解题思路

该问题要求实现一个简易内存池,支持两种操作命令:REQUESTRELEASE

  • REQUEST 表示请求分配指定大小内存,

  • RELEASE 表示释放之前分配的内存。

内存池总大小为 100 字节,地址分配必须是连续内存,并优先从低地址分配。

解题思路主要包括以下几个步骤:

  1. 定义内存池的大小、内存使用状态、已分配内存的字典(映射首地址到内存大小)。
  2. 实现 request 方法,用于处理请求分配内存的操作。遍历内存池,找到连续的空闲内存块,并记录已分配的内存块。
  3. 实现 release 方法,用于处理释放内存的操作。在已分配的内存块中查找要释放的地址,将其标记为空闲状态。
  4. main 函数中,根据输入命令调用相应方法,输出结果。

Java

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;


/**
 * @author code5bug
 */
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = Integer.parseInt(in.nextLine());
        Solution solution = new Solution();
        for (int i = 0; i < n; i++) {
            String[] split = in.nextLine().split("=");
            int val = Integer.parseInt(split[1]);
            if ("REQUEST".equals(split[0])) {
                // 申请内存
                solution.request(val);
            } else {
                // 释放内存
                solution.release(val);
            }
        }
    }
}

class Solution {
    // 声明一个静态字符串变量,用于表示错误信息
    public static String ERROR = "error";

    // 内存大小
    private int size;
    // 内存使用状态
    private boolean[] mem;

    // 已经使用的内存<首地址, 内存大小>
    private Map<Integer, Integer> used = new HashMap<>();

    public Solution() {
        this.size = 100;
        this.mem = new boolean[size];
    }

    // 申请内存
    public void request(int val) {
        if (val == 0 || val > 100) {
            System.out.println(ERROR);
            return;
        }

        for (int i = 0; i < size; i++) {
            // 当前内存已被使用
            if (mem[i]) continue;

            int cnt = 0;  // 空闲的连续内存大小
            while (i + cnt < size && !mem[i + cnt]) cnt++;

            // 空间足够分配
            if (cnt >= val) {
                // 记录已经申请的内存片段
                used.put(i, val);

                // 标记内存点已被使用
                while (--val >= 0) mem[i + val] = true;

                System.out.println(i);
                return;
            }

            i += cnt;
        }

        System.out.println(ERROR);
    }

    // 释放内存
    public void release(int addr) {
        if (!used.containsKey(addr)) {  // 不存在的首地址
            System.out.println(ERROR);
            return;
        }

        // 释放内存片段
        int s = addr, len = used.get(s);
        // 标记内存点空闲
        for (int i = 0; i < len; i++) mem[s + i] = false;
        used.remove(addr);
    }
}


Python

class Solution:
    # 类变量,用于表示错误信息
    ERROR = "error"

    def __init__(self):
        self.size = 100
        # 内存使用状态
        self.mem = [False] * self.size
        # 已经使用的内存 {首地址: 内存大小}
        self.used = {}

    # 申请内存
    def request(self, val):
        if val == 0 or val > 100:
            print(self.ERROR)
            return

        i = 0
        while i < self.size:
            # 当前内存已被使用
            if self.mem[i]:
                i += 1
                continue

            cnt = 0  # 空闲的连续内存大小
            while i + cnt < self.size and not self.mem[i + cnt]:
                cnt += 1

            # 空间足够分配
            if cnt >= val:
                # 记录已经申请的内存片段
                self.used[i] = val

                # 标记内存点已被使用
                for j in range(val):
                    self.mem[i + j] = True

                print(i)
                return

            i += cnt

        print(self.ERROR)

    # 释放内存
    def release(self, addr):
        if addr not in self.used:  # 不存在的首地址
            print(self.ERROR)
            return

        # 释放内存片段
        s, length = addr, self.used[addr]
        # 标记内存点空闲
        for i in range(length):
            self.mem[s + i] = False
        del self.used[addr]


def main():
    n = int(input())
    solution = Solution()

    for _ in range(n):
        relation = input().split("=")
        val = int(relation[1])

        if relation[0] == "REQUEST":
            # 申请内存
            solution.request(val)
        else:
            # 释放内存
            solution.release(val)


if __name__ == "__main__":
    main()

C++

#include <iostream>
#include <unordered_map>
#include <vector>
#include <sstream>

using namespace std;

void request(vector<bool>& mem, unordered_map<int, int>& used, int val) {
    const int size = mem.size();

    if (val == 0 || val > size) {
        cout << "error" << endl;
        return;
    }

    for (int i = 0; i < size; ) {
        if (mem[i]) {
            ++i;
            continue;
        }

        int cnt = 0;  // 空闲的连续内存大小
        while (i + cnt < size && !mem[i + cnt]) {
            ++cnt;
        }

        if (cnt >= val) {
            used[i] = val;

            for (int j = 0; j < val; ++j) {
                mem[i + j] = true;
            }

            cout << i << endl;
            return;
        }

        i += cnt;
    }

    cout << "error" << endl;
}

void release(vector<bool>& mem, unordered_map<int, int>& used, int addr) {
    if (used.find(addr) == used.end()) {
        cout << "error" << endl;
        return;
    }

    int len = used[addr];

    for (int i = 0; i < len; ++i) {
        mem[addr + i] = false;
    }

    used.erase(addr);
}

int main() {
    int n;
    cin >> n;
    cin.ignore();  // Consume the newline after n

    const int size = 100;
    // 内存使用状态
    vector<bool> mem(size, false);
    // 已经使用的内存<首地址, 内存大小>
    unordered_map<int, int> used;

    for (int i = 0; i < n; ++i) {
        string line;
        getline(cin, line);
        int    pos       = line.find('=');
        string operation = line.substr(0, pos);
        int    val       = stoi(line.substr(pos + 1));

        if (operation == "REQUEST") {
            request(mem, used, val);
        } else {
            release(mem, used, val);
        }
    }

    return 0;
}

‍❤️‍华为OD机试面试交流群每日真题分享): 加V时备注“华为od加群”

🙏整理题解不易, 如果有帮助到您,请给点个赞 ‍❤️‍ 和收藏 ⭐,让更多的人看到。🙏🙏🙏

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1484120.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

golang学习5,glang的web的restful接口

1. //返回json r.GET("/getJson", controller.GetUserInfo) package mainimport (/*"net/http"*/"gin/src/main/controller""github.com/gin-gonic/gin" )func main() {r : gin.Default()r.GET("/get", func(ctx *…

【研发日记】Matlab/Simulink技能解锁(三)——在Stateflow编辑窗口Debug

文章目录 前言 State断点 Transition断点 条件断点 按State步进 Watch Data Value Sequence Viewer 分析和应用 总结 前言 见《【研发日记】Matlab/Simulink技能解锁(一)——在Simulink编辑窗口Debug》 见《【研发日记】Matlab/Simulink技能解锁(二)——在Function编辑…

数据结构开篇

目录 一. 如何学好数据结构二. 基本概念和术语2.1 区分数据、数据元素、数据项、数据对象2.2 数据结构2.2.1 逻辑结构2.2.2 存储结构 2.3 数据类型和抽象数据类型2.4 抽象数据类型的实现 \quad 一. 如何学好数据结构 勤于思考;多做练习;多上机;善于寻求帮助;不怕困难&#xff…

NLP算法实战项目:使用 BERT 进行文本多分类

大多数研究人员将他们的研究论文提交给学术会议&#xff0c;因为这是更快地使研究结果可用的途径。寻找和选择合适的会议一直是一项具有挑战性的任务&#xff0c;特别是对于年轻的研究人员来说。基于先前会议论文集的数据&#xff0c;研究人员可以增加其论文被接受和发表的机会…

基于协同过滤算法的图书推荐系统

目录 一、功能介绍 二、开发环境 三、安装部署说明 一、功能介绍 本系统是一个采用协同过滤算法的图书推荐系统。 数据集&#xff1a;数据集来自亚马逊开源的Book-Crossings数据集。Book-Crossings数据集包含 278,858 个用户的 271,379 本书的 1,149,780 个评分。评分范围从1…

FL Studio选购指南:新手小白应该选择哪个版本FL Studio?

很多打算入手正版FL Studio的新手朋友都会纠结一个问题&#xff1a;哪个版本的FL Studio更适合我&#xff0c;到底应该入手哪一款FL Studio&#xff1f;本文会介绍每个版本之间的差异点&#xff0c;并带大家选择适合自己的FL Sudio版本。 FL Studio全版本 在选购前有一些小知识…

25高数考研张宇 -- 公式总结(更新中)

1. 两个重要极限 (1) lim ⁡ x → 0 sin ⁡ x x 1 \lim _{x \rightarrow 0} \frac{\sin x}{x}1 limx→0​xsinx​1, 推广形式 lim ⁡ f ( x ) → 0 sin ⁡ f ( x ) f ( x ) 1 \lim _{f(x) \rightarrow 0} \frac{\sin f(x)}{f(x)}1 limf(x)→0​f(x)sinf(x)​1. (2) lim ⁡…

小项目:2024/3/2

一、TCP机械臂测试 代码&#xff1a; #include <myhead.h> #define SER_IP "192.168.125.254" //服务器端IP #define SER_PORT 8888 //服务器端端口号#define CLI_IP "192.168.199.131" //客户端IP #define CLI_P…

Linux线程【互斥与同步】

目录 1.资源共享问题 1.1多线程并发访问 1.2临界区和临界资源 1.3互斥锁 2.多线程抢票 2.1并发抢票 2.2 引发问题 3.线程互斥 3.1互斥锁相关操作 3.1.1互斥锁创建与销毁 3.1.2、加锁操作 3.1.3 解锁操作 3.2.解决抢票问题 3.2.1互斥锁细节 3.3互斥…

[NSSCTF 2nd] web复现

1.php签到 <?phpfunction waf($filename){$black_list array("ph", "htaccess", "ini");$ext pathinfo($filename, PATHINFO_EXTENSION);foreach ($black_list as $value) {if (stristr($ext, $value)){return false;}}return true; }if(i…

【Spring IoC】实验四:特殊值处理

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大三在校生&#xff0c;喜欢AI编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;落798. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc;️…

【NDK系列】Android tombstone文件分析

文件位置 data/tombstone/tombstone_xx.txt 获取tombstone文件命令&#xff1a; adb shell cp /data/tombstones ./tombstones 触发时机 NDK程序在发生崩溃时&#xff0c;它会在路径/data/tombstones/下产生导致程序crash的文件tombstone_xx&#xff0c;记录了死亡了进程的…

electron nsis 安装包 window下任务栏无法正常固定与取消固定 Pin to taskbar

问题 win10系统下&#xff0c;程序任务栏在固定后取消固定&#xff0c;展示的程序内容异常。 排查 1.通过论坛查询&#xff0c;应该是与app的api setAppUserModelId 相关 https://github.com/electron/electron/issues/3303 2.electron-builder脚本 electron-builder…

ABAP - SALV教程04 添加状态栏

CL_SALV_TABLE中提供了 GET_FUNCTIONS方法.GET_FUNCTIONS方法返回的是一个CL_SALV_FUNCTIONS_LIST类型的实例对象. 类CL_SALV_FUNCTIONS_LIST两个方法(SET_ALL、SET_DEFAULT)可以添加标准状态栏 实现步骤: 定义SET_STATUS私有方法. PRIVATE SECTION.METHODS:set_status CHA…

qt 基于百度API的人脸识别

百度云官网&#xff1a;点击跳转 一、创建应用 跳转进去&#xff0c;可以看到以下界面&#xff1a; 点击红色圈内的“去创建”&#xff0c;创建自己的项目。可以看到以下界面&#xff1a; 输入“应用名称”&#xff0c;并勾选“人脸对比”&#xff0c;还要到页面的最后输入“应…

董兆祥出席工业废水资源化,开创变废为宝新途径演讲

演讲嘉宾&#xff1a;董兆祥 董事长 河北奥博水处理有限公司 演讲题目&#xff1a;工业废水资源化&#xff0c;开创变废为宝新途径 会议简介 “十四五”规划中提出&#xff0c;提高工业、能源领城智能化与信息化融合&#xff0c;明确“低碳经济”新的战略目标&#xff0c;热…

C++之stack

1、stack简介 stack是实现的一个先进后出&#xff0c;后进先出的容器。它只有一个出口&#xff0c;只能操作最顶端元素。 2、stack库函数 &#xff08;1&#xff09;push() //向栈压入一个元素 &#xff08;2&#xff09;pop() //移除栈顶元素 &#xff08;3…

‘conda‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件

如果你在运行 conda 命令时收到了 ‘conda’ 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件。 的错误消息&#xff0c;这可能意味着 Anaconda 并没有正确地添加到你的系统路径中。 1.你可以尝试手动添加 Anaconda 到系统路径中。以下是在 Windows 系统上添加…

RPA中国 x UiPath | 第六届RPA极客挑战赛,3月16日上海开赛!

随着人工智能技术的不断进步以及数字化转型的深入&#xff0c;企业对于高效、精准、自动化的业务流程需求日益迫切。RPA技术作为连接人类工作与机器操作的桥梁&#xff0c;正逐渐从规则驱动发展为智能决策的助手。 由RPA中国联合UiPath共同主办的【第六届RPA极客挑战赛】将于2…

利用AI生成内容推广吸粉推广营销影响力全自动化工具

利用AI生成内容推广吸粉影响力全自动化工具 步骤 1、采集热门关键词 2、用各大平台AI接口生成各种角度文章或视频 3、发布到各平台 细节 您提到的利用人工智能&#xff08;AI&#xff09;生成内容并推广吸粉的全自动化工具&#xff0c;在当前技术条件下是可能的。下面是一个…