【华为OD机试E卷真题】 内存资源分配 | 原题+思路+多语言代码(本题100%)(C++、Java、Py)

华为OD机试E卷真题 内存资源分配 | 原题+思路+多语言代码(本题100%)(C++、Java、Py)

题目描述

有一个简易内存池,内存按照大小粒度分类,每个粒度有若干个可用内存资源,用户会进行一系列内存申请,需要按需分配内存池中的资源返回申请结果成功失败列表。

分配规则如下:

  • 分配的内存要大于等于内存的申请量,存在满足需求的内存就必须分配,优先分配粒度小的,但内存不能拆分使用;
  • 需要按申请顺序分配,先申请的先分配,有可用内存分配则申请结果为true;
  • 没有可用则返回false。

注意:不考虑内存释放

输入描述

输入为两行字符串

第一行为内存池资源列表,包含内存粒度数据信息,粒度数据间用逗号分割

  • 一个粒度信息内用冒号分割,冒号前为内存粒度大小,冒号后为数量
  • 资源列表不大于1024
  • 每个粒度的数量不大于4096

第二行为申请列表,申请的内存大小间用逗号分割

  • 申请列表不大于100000

如:

64:2,128:1,32:4,1:128

50,36,64,128,127

输出描述

输出为内存池分配结果

如true,true,true,false,false

示例1

输入

64:2,128:1,32:4,1:128
50,36,64,128,127

输出

true,true,true,false,false

说明

内存池资源包含:64K共2个、128K共1个、32K共4个、1K共128个的内存资源;
针对50,36,64,128,127的内存申请序列,分配的内存依次是:64,64,128,NULL,NULL,
第三次申请内存时已经将128分配出去,因此输出结果是:
true,true,true,false,false

解题思路

  1. 解析内存池资源

    • 将内存池资源列表解析为一个字典,键为内存粒度大小,值为该粒度的可用数量。

  2. 排序内存粒度

    • 将内存粒度按从小到大的顺序排序,以便在分配时优先选择较小的粒度。

  3. 处理内存申请

    • 对于每个申请,遍历排序后的内存粒度,找到第一个大于等于申请大小且有可用资源的粒度。

    • 如果找到,分配该粒度的内存,减少其可用数量,并记录申请成功。

    • 如果没有找到,记录申请失败。

代码

java

import java.util.*;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String resources = scanner.nextLine();
        String requests = scanner.nextLine();
        scanner.close();

        // 解析内存池资源
        Map<Integer, Integer> resourceMap = new HashMap<>();
        String[] resourceItems = resources.split(",");
        for (String item : resourceItems) {
            String[] parts = item.split(":");
            int size = Integer.parseInt(parts[0]);
            int count = Integer.parseInt(parts[1]);
            resourceMap.put(size, count);
        }

        // 将内存粒度按从小到大排序
        List<Integer> sortedSizes = resourceMap.keySet().stream().sorted().collect(Collectors.toList());

        // 解析申请列表
        String[] requestItems = requests.split(",");
        List<Boolean> results = new ArrayList<>();

        for (String request : requestItems) {
            int reqSize = Integer.parseInt(request.trim());
            boolean allocated = false;

            // 遍历排序后的内存粒度
            for (int size : sortedSizes) {
                if (size >= reqSize && resourceMap.get(size) > 0) {
                    // 分配内存
                    resourceMap.put(size, resourceMap.get(size) - 1);
                    results.add(true);
                    allocated = true;
                    break;
                }
            }

            if (!allocated) {
                results.add(false);
            }
        }

        // 输出结果
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < results.size(); i++) {
            if (i > 0) {
                sb.append(",");
            }
            sb.append(results.get(i));
        }
        System.out.println(sb.toString());
    }
}

python

def main():
    import sys
    input = sys.stdin.read().split('\n')
    resources = input[0]
    requests = input[1]

    # 解析内存池资源
    resource_map = {}
    for item in resources.split(','):
        size, count = item.split(':')
        resource_map[int(size)] = int(count)

    # 将内存粒度按从小到大排序
    sorted_sizes = sorted(resource_map.keys())

    # 解析申请列表
    request_list = list(map(int, requests.split(',')))
    results = []

    for req_size in request_list:
        allocated = False
        # 遍历排序后的内存粒度
        for size in sorted_sizes:
            if size >= req_size and resource_map[size] > 0:
                # 分配内存
                resource_map[size] -= 1
                results.append(True)
                allocated = True
                break
        if not allocated:
            results.append(False)

    # 输出结果
    print(','.join(map(str, results)))

if __name__ == "__main__":
    main()

c++

#include <iostream>
#include <vector>
#include <map>
#include <sstream>
#include <algorithm>
using namespace std;

int main() {
    string resources, requests;
    getline(cin, resources);
    getline(cin, requests);

    // 解析内存池资源
    map<int, int> resource_map;
    istringstream res_stream(resources);
    string item;
    while (getline(res_stream, item, ',')) {
        size_t colon_pos = item.find(':');
        int size = stoi(item.substr(0, colon_pos));
        int count = stoi(item.substr(colon_pos + 1));
        resource_map[size] = count;
    }

    // 解析申请列表
    vector<int> request_list;
    istringstream req_stream(requests);
    string req;
    while (getline(req_stream, req, ',')) {
        request_list.push_back(stoi(req));
    }

    vector<bool> results;
    for (int req_size : request_list) {
        bool allocated = false;
        // 遍历排序后的内存粒度
        for (auto it = resource_map.begin(); it != resource_map.end(); ++it) {
            int size = it->first;
            int &count = it->second;
            if (size >= req_size && count > 0) {
                // 分配内存
                count--;
                results.push_back(true);
                allocated = true;
                break;
            }
        }
        if (!allocated) {
            results.push_back(false);
        }
    }

    // 输出结果
    for (size_t i = 0; i < results.size(); i++) {
        if (i > 0) {
            cout << ",";
        }
        cout << results[i];
    }
    cout << endl;

    return 0;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值