C++高频知识点(二十四)
文章目录
- 116. 写一段代码:实现一个有getMin功能的栈
- 基本思路
- 代码实现
- 帮助加深理解
- 117. 如果让你优化加速一个算法,你有什么思路?
- 118. 描述一下delete[]的处理过程
- 1. 数组元素的析构函数调用:
- 2. 释放内存:
- delete[] 与 delete 的区别:
- 注意事项
- 1. 匹配分配和释放方式:
- 2. 指向单个对象的指针不应该使用 delete[]:
- 119. 为什么要main函数?
- 120. 说一下 GPU运行过程
- CPU 和 GPU 的协作
- CPU 控制任务
- 120.1.2 GPU 并行计算流程
116. 写一段代码:实现一个有getMin功能的栈
基本思路
要实现一个带有 getMin() 功能的栈,可以通过在普通栈的基础上,使用另一个辅助栈来记录最小值。辅助栈保证在每次元素入栈或出栈时,栈顶元素始终为当前栈中的最小值。也就是说你要实现的这个栈,其实里面包含了两个真正的Stack
代码实现
下面是一个实现带 getMin() 功能的栈的C++代码的实现,
#include <iostream>
#include <stack>
#include <stdexcept>
using namespace std;class MinStack {
private:stack<int> mainStack; // 用于存储实际元素的栈stack<int> minStack; // 用于存储当前最小值的栈public:// 入栈操作void push(int x) {mainStack.push(x);// 如果minStack为空或当前元素小于等于minStack栈顶元素,则将该元素压入minStackif (minStack.empty() || x <= minStack.top()) {minStack.push(x);}}// 出栈操作void pop() {if (mainStack.empty()) {throw out_of_range("Stack is empty");}// 如果当前出栈的元素是最小值,则minStack也出栈if (mainStack.top() == minStack.top()) {minStack.pop();}mainStack.pop();}// 获取栈顶元素int top() {if (mainStack.empty()) {throw out_of_range("Stack is empty");}return mainStack.top();}// 获取栈中的最小值int getMin() {if (minStack.empty()) {throw out_of_range("Stack is empty");}return minStack.top();}
};int main() {MinStack minStack;minStack.push(5);minStack.push(3);minStack.push(7);cout << "当前最小值: " << minStack.getMin() << endl; // 输出 3minStack.pop();cout << "栈顶元素: " << minStack.top() << endl; // 输出 3cout << "当前最小值: " << minStack.getMin() << endl; // 输出 3minStack.pop();cout << "当前最小值: " << minStack.getMin() << endl; // 输出 5return 0;
}
帮助加深理解
咱们来举个栗子,假设有如下的入栈和出栈操作顺序:
minStack.push(5); // 5 被压入 mainStack 和 minStack
minStack.push(3); // 3 被压入 mainStack 和 minStack,因为 3 < 5
minStack.push(7); // 7 只被压入 mainStack,因为 7 > 3
minStack.pop(); // 7 出栈,但 minStack 保持不变,最小值仍是 3
minStack.push(2); // 2 被压入 mainStack 和 minStack,因为 2 < 3
117. 如果让你优化加速一个算法,你有什么思路?
118. 描述一下delete[]的处理过程
delete[] 是 C++ 中用于释放通过 new[] 分配的数组内存的运算符。与普通的 delete 相比,delete[] 有一个关键区别:它不仅释放数组占用的内存,还会确保对数组中的每个元素调用适当的析构函数。
1. 数组元素的析构函数调用:
当你使用 new[] 分配了一个包含对象的数组时,delete[] 会遍历数组中的每个对象,并对它们逐一调用析构函数。如果数组中的对象是类类型的,析构函数会释放对象内部可能持有的资源(如内存、文件句柄等)。
例如,假设我们有一个类 MyClass,它在析构时释放某些资源:
class MyClass {
public:~MyClass() {cout << "Destructor called" << endl;}
};int main() {MyClass* arr = new MyClass[3]; // 分配 3 个对象的数组delete[] arr; // 释放数组,并调用每个对象的析构函数
}
在这段代码中,delete[] arr; 会调用 MyClass 的析构函数 3 次。
2. 释放内存:
在调用完所有元素的析构函数后,delete[] 会释放数组所占的内存块。 这与 delete 的处理方式相同,释放通过 new[] 分配的整个内存块。底层可能使用 free() 或其他内存释放机制来完成这个操作。
delete[] 与 delete 的区别:
- delete 只用于单个对象,调用单个对象的析构函数并释放内存。
- delete[] 用于数组,会逐个调用数组中所有对象的析构函数,然后释放整个数组的内存。
注意事项
1. 匹配分配和释放方式:
必须使用 delete[] 来释放通过 new[] 分配的数组。如果使用 delete 释放通过 new[] 分配的数组,结果是未定义行为,因为 delete 不会调用所有对象的析构函数。
int* arr = new int[10];
delete[] arr; // 正确
如果不使用 delete[],则会导致资源泄漏或者其他未定义行为:
int* arr = new int[10];
delete arr; // 错误,未定义行为
2. 指向单个对象的指针不应该使用 delete[]:
如果用 new 分配了单个对象,应该用 delete 来释放,而不是 delete[],意思也就是说这两个家伙不能混用:
MyClass* obj = new MyClass;
delete obj; // 正确,使用 `delete` 释放单个对象
119. 为什么要main函数?
120. 说一下 GPU运行过程
GPU(图形处理单元)运行过程是指 GPU 在执行计算任务时,如何从主机 CPU 接收指令、加载数据、并行执行任务并返回结果的整个流程。GPU 由于其大量并行计算核心,能够在处理大规模计算任务(如图形渲染、科学计算、机器学习等)时,显著加快运算速度。
CPU 和 GPU 的协作
在典型的系统中,CPU(中央处理器) 控制整个计算任务的执行,包括管理内存、调度任务、控制数据的输入输出等。GPU 则专门负责高效地执行大量可以并行化的计算任务。
CPU 控制任务
120.1.2 GPU 并行计算流程
GPU 通过以下步骤执行任务:
之后我会持续更新,如果喜欢我的文章,请记得一键三连哦,点赞关注收藏,你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 !!!↖(▔▽▔)↗感谢支持!