OD统一考试(C卷)
分值: 200分
题解: Java / Python / C++
题目描述
请实现一个简易内存池,根据请求命令完成内存分配和释放。
内存池支持两种操作命令,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
题解
解题思路
该问题要求实现一个简易内存池,支持两种操作命令:
REQUEST
和RELEASE
。
REQUEST
表示请求分配指定大小内存,
RELEASE
表示释放之前分配的内存。内存池总大小为 100 字节,地址分配必须是连续内存,并优先从低地址分配。
解题思路主要包括以下几个步骤:
- 定义内存池的大小、内存使用状态、已分配内存的字典(映射首地址到内存大小)。
- 实现
request
方法,用于处理请求分配内存的操作。遍历内存池,找到连续的空闲内存块,并记录已分配的内存块。- 实现
release
方法,用于处理释放内存的操作。在已分配的内存块中查找要释放的地址,将其标记为空闲状态。- 在
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加群”
🙏整理题解不易, 如果有帮助到您,请给点个赞 ❤️ 和收藏 ⭐,让更多的人看到。🙏🙏🙏