华为OD机试 2025A卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试真题(Java/Python/JS/C/C++)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。
一、题目描述
请实现一个简易内存池,根据请求命令完成内存分配和释放。
内存池支持两种操作命令,REQUEST和RELEASE,其格式为:
1、REQUEST
请求的内存大小表示请求分配指定大小内存,如果分配成功,返回分配到的内存首地址;如果内存不足,或指定的大小为0,则输出error。
2、RELEASE
释放的内存首地址 表示释放掉之前分配的内存,释放成功无需输出,如果释放不存在的首地址则输出error。
注意:
1.内存池总大小为100字节。
2.内存池地址分配必须是连续内存,并优先从低地址分配。
3.内存释放后可被再次分配,已释放的内存在空闲时不能被二次释放。
4.不会释放已申请的内存块的中间地址。
5.释放操作只是针对首地址所对应的单个内存块进行操作,不会影响其它内存块。
二、输入描述
首行为整数N,表示操作命令的个数。
接下来的N行,每行将给出一个操作命令,操作命令和参数之间用“=”分割
三、输出描述
输出最后请求的内存的首地址。
如果位置已满,则输出-1。
样例:
2
REQUEST=10
REQUEST=20
输出样例:
0
10
四、解题思路
- 定义一个map,存储内存的分配情况(key:内存的首地址,value:内存的尾地址);
- 请求内存时
- 如果map是空,放在首地址0处;
- 如果map不为空,遍历已经存入的首地址;
- 已经存入的首地址 - 第一个空闲区域的首地址 大于 请求的内存值;
- 将当前请求的内存的首地址和内存的尾地址存入map;
- 反之,重置前一个空闲区域的首地址;
- 判断剩余内存是否可以容下当前请求值;
- 如果可以容下,将当前请求的内存的首地址和内存的尾地址存入map;
- 如果容不下,输出error;
- 释放内存时,将其首地址的key移除map;
- 最后输出最后一次请求的首地址。
注意:如果最后发起的命令是RELEASE,也是可以的,会返回最后一次REQUEST的首地址。
五、测试用例
1、输入
4
REQUEST=20
REQUEST=30
RELEASE=0
REQUEST=30
2、输出
50
3、说明
- 第一次请求20
- 第二请求30
- 第三次释放首地址为0的内存
- 第四次请求30,第一个空闲区域的首地址是0,但空闲长度只有20,放不下当前请求的地址,因此消耗剩余内存,输出最后一次请求的首地址为50。
4、再输入
6
REQUEST=20
REQUEST=30
RELEASE=0
REQUEST=30
REQUEST=10
REQUEST=10
5、再说明
- 第一次请求20
- 第二请求30
- 第三次释放首地址为0的内存
- 第四次请求30,第一个空闲区域的首地址是0,但空闲长度只有20,放不下当前请求的地址,因此消耗剩余内存。
- 第五次请求10,第一个空闲区域的首地址是0,长度20,可以容下当前请求的内存10。
- 第六次请求10,第一个空闲区域的首地址是10,长度10,可以容下当前请求的内存10。
- 输出最后一次请求的首地址为10。
6、如果走后一次请求的是20,会怎么样呢?
六、Python算法源码
class MemoryManager:
REQUEST = "REQUEST"
RELEASE = "RELEASE"
ERROR = "error"
MAX = 100
def __init__(self):
self.memory_map = {}
def main(self):
try:
# 操作命令的个数
N = int(input().strip())
# 每一行的操作命令和参数
line_arr = [input().strip().split('=') for _ in range(N)]
for command, value_str in line_arr:
value = int(value_str)
if command.startswith(self.REQUEST): # 请求
# 非法输入(内存池总大小为100字节)
if value > self.MAX or value <= 0:
print(self.ERROR)
return
self.request(value)
elif command.startswith(self.RELEASE): # 释放
self.memory_map.pop(value, None)
else: # 非法输入
print(self.ERROR)
except Exception as e:
# 非法输入
print(self.ERROR)
def request(self, value):
zero = 0
before_head_address = 0
if not self.memory_map: # 如果memory_map是空,放在首地址0处
self.memory_map[zero] = value
print(zero)
else:
head_list = sorted(self.memory_map.keys())
for requested_head in head_list:
if requested_head - before_head_address >= value:
self.memory_map[before_head_address] = before_head_address + value
print(before_head_address)
return
else:
before_head_address = self.memory_map[requested_head]
if self.MAX - before_head_address >= value:
self.memory_map[before_head_address] = before_head_address + value
print(before_head_address)
else:
print("-1")
if __name__ == "__main__":
MemoryManager().main()
七、JavaScript算法源码
class MemoryManager {
constructor() {
this.REQUEST = "REQUEST";
this.RELEASE = "RELEASE";
this.ERROR = "error";
this.MAX = 100;
this.memoryMap = new Map(); // 用于存储内存的分配情况
}
main() {
try {
const input = require('readline-sync');
// 操作命令的个数
const N = parseInt(input.question().trim());
// 每一行的操作命令和参数
const lineArr = [];
for (let i = 0; i < N; i++) {
lineArr.push(input.question().trim().split('='));
}
for (let i = 0; i < N; i++) {
const [command, valueStr] = lineArr[i];
const value = parseInt(valueStr);
if (command.startsWith(this.REQUEST)) { // 请求
// 非法输入(内存池总大小为100字节)
if (value > this.MAX || value <= 0) {
console.log(this.ERROR);
return;
}
this.request(value);
} else if (command.startsWith(this.RELEASE)) { // 释放
this.memoryMap.delete(value);
} else { // 非法输入
console.log(this.ERROR);
}
}
} catch (e) {
// 非法输入
console.log(this.ERROR);
}
}
request(value) {
let zero = 0;
let beforeHeadAddress = 0;
if (this.memoryMap.size === 0) { // 如果memoryMap是空,放在首地址0处
this.memoryMap.set(zero, value);
console.log(zero);
} else {
const headList = Array.from(this.memoryMap.keys()).sort((a, b) => a - b);
for (let requestedHead of headList) {
if (requestedHead - beforeHeadAddress >= value) {
this.memoryMap.set(beforeHeadAddress, beforeHeadAddress + value);
console.log(beforeHeadAddress);
return;
} else {
beforeHeadAddress = this.memoryMap.get(requestedHead);
}
}
if (this.MAX - beforeHeadAddress >= value) {
this.memoryMap.set(beforeHeadAddress, beforeHeadAddress + value);
console.log(beforeHeadAddress);
} else {
console.log("-1");
}
}
}
}
// 执行内存管理器
const memoryManager = new MemoryManager();
memoryManager.main();
八、C算法源码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define REQUEST "REQUEST"
#define RELEASE "RELEASE"
#define ERROR "error"
#define MAX 100
typedef struct MemoryBlock {
int start;
int end;
struct MemoryBlock* next;
} MemoryBlock;
MemoryBlock* head = NULL;
void request(int value);
void release(int value);
void print_error();
void print_memory_address(int address);
int main() {
int N;
scanf("%d", &N);
for (int i = 0; i < N; i++) {
char command[10];
int value;
scanf("%s=%d", command, &value);
if (strncmp(command, REQUEST, strlen(REQUEST)) == 0) {
if (value > MAX || value <= 0) {
print_error();
return 0;
}
request(value);
} else if (strncmp(command, RELEASE, strlen(RELEASE)) == 0) {
release(value);
} else {
print_error();
return 0;
}
}
return 0;
}
void request(int value) {
int beforeHeadAddress = 0;
if (head == NULL) {
// 如果链表为空,放在首地址0处
MemoryBlock* newBlock = (MemoryBlock*)malloc(sizeof(MemoryBlock));
newBlock->start = 0;
newBlock->end = value;
newBlock->next = NULL;
head = newBlock;
print_memory_address(0);
} else {
MemoryBlock* current = head;
MemoryBlock* prev = NULL;
while (current != NULL) {
if (current->start - beforeHeadAddress >= value) {
MemoryBlock* newBlock = (MemoryBlock*)malloc(sizeof(MemoryBlock));
newBlock->start = beforeHeadAddress;
newBlock->end = beforeHeadAddress + value;
newBlock->next = current;
if (prev == NULL) {
head = newBlock;
} else {
prev->next = newBlock;
}
print_memory_address(newBlock->start);
return;
}
beforeHeadAddress = current->end;
prev = current;
current = current->next;
}
if (MAX - beforeHeadAddress >= value) {
MemoryBlock* newBlock = (MemoryBlock*)malloc(sizeof(MemoryBlock));
newBlock->start = beforeHeadAddress;
newBlock->end = beforeHeadAddress + value;
newBlock->next = NULL;
prev->next = newBlock;
print_memory_address(newBlock->start);
} else {
print_memory_address(-1);
}
}
}
void release(int value) {
MemoryBlock* current = head;
MemoryBlock* prev = NULL;
while (current != NULL) {
if (current->start == value) {
if (prev == NULL) {
head = current->next;
} else {
prev->next = current->next;
}
free(current);
return;
}
prev = current;
current = current->next;
}
}
void print_error() {
printf("%s\n", ERROR);
}
void print_memory_address(int address) {
printf("%d\n", address);
}
九、C++算法源码
#include <iostream>
#include <map>
#include <string>
using namespace std;
class MemoryManager {
public:
static const int MAX = 100;
const string REQUEST = "REQUEST";
const string RELEASE = "RELEASE";
const string ERROR = "error";
void main() {
try {
int N;
cin >> N;
cin.ignore(); // 忽略换行符
string lineArr[N][2];
for (int i = 0; i < N; ++i) {
string command;
getline(cin, command);
size_t pos = command.find('=');
if (pos != string::npos) {
lineArr[i][0] = command.substr(0, pos);
lineArr[i][1] = command.substr(pos + 1);
}
}
for (int i = 0; i < N; ++i) {
int value = stoi(lineArr[i][1]);
if (lineArr[i][0].find(REQUEST) == 0) { // 请求
if (value > MAX || value <= 0) {
cout << ERROR << endl;
return;
}
request(value);
} else if (lineArr[i][0].find(RELEASE) == 0) { // 释放
memoryMap.erase(value);
} else { // 非法输入
cout << ERROR << endl;
}
}
} catch (...) {
// 非法输入
cout << ERROR << endl;
}
}
private:
map<int, int> memoryMap;
void request(int value) {
int beforeHeadAddress = 0;
if (memoryMap.empty()) { // 如果memoryMap是空,放在首地址0处
memoryMap[0] = value;
cout << 0 << endl;
} else {
for (auto it = memoryMap.begin(); it != memoryMap.end(); ++it) {
if (it->first - beforeHeadAddress >= value) {
memoryMap[beforeHeadAddress] = beforeHeadAddress + value;
cout << beforeHeadAddress << endl;
return;
}
beforeHeadAddress = it->second;
}
if (MAX - beforeHeadAddress >= value) {
memoryMap[beforeHeadAddress] = beforeHeadAddress + value;
cout << beforeHeadAddress << endl;
} else {
cout << "-1" << endl;
}
}
}
};
int main() {
MemoryManager memoryManager;
memoryManager.main();
return 0;
}
🏆本文收录于,华为OD机试真题(Python/JS/C/C++)
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。