每日一道编程题
class MinStack {
public:
// 存储栈中元素及其出现次数的映射
map<int, int> m;
// 存储实际栈元素的栈
stack<int> s1;
// 记录当前栈中的最小元素
int min_num;
MinStack() {
// 初始化时将最小元素设为整型最大值
min_num = INT_MAX;
}
void push(int val) {
// 将元素入栈
s1.push(val);
// 更新元素在映射中的出现次数
m[val]++;
// 如果新入栈的元素小于当前最小元素,则更新最小元素
if (val < min_num) min_num = val;
}
void pop() {
int topval = s1.top();
// 减少栈顶元素在映射中的出现次数
m[topval]--;
// 弹出栈顶元素
s1.pop();
// 如果弹出的元素是当前最小元素且其在映射中的出现次数变为 0
if (topval == min_num && m[topval] == 0) {
min_num = INT_MAX;
// 重新寻找新的最小元素
for (const auto& pair : m) {
if (pair.second > 0 && pair.first < min_num) {
min_num = pair.first;
break;
}
}
}
}
int top() {
// 返回栈顶元素
return s1.top();
}
int getMin() {
// 返回当前栈中的最小元素
return min_num;
}
};
C++ 中类的三大特性是什么?请简要解释。
- 封装:
- 解释:封装是将数据和操作数据的方法封装在一个类中,通过访问修饰符(如 public、private 和 protected)来控制对类成员的访问。
- 作用:封装可以隐藏类的内部实现细节,提高代码的安全性和可维护性。外部代码只能通过类提供的公共接口来访问和操作类的成员,而不能直接访问类的私有成员,从而避免了对数据的意外修改和错误使用。
- 继承:
- 解释:继承允许一个类(派生类)继承另一个类(基类)的属性和方法。派生类可以扩展和修改基类的功能,同时继承基类的特性。
- 作用:继承可以实现代码的复用,减少重复代码的编写。通过继承,可以建立类之间的层次关系,使得代码更加清晰和易于理解。同时,继承也可以实现多态性,通过基类指针或引用来调用派生类的函数。
- 多态:
- 解释:多态是指同一个操作作用于不同的对象可以有不同的表现形式。在 C++ 中,多态主要通过虚函数和函数重载来实现。
- 作用:多态可以提高代码的灵活性和可扩展性。通过多态,可以根据对象的实际类型来调用相应的函数,而不需要在编译时确定具体的函数调用。这使得代码更加通用,可以适应不同类型的对象和变化的需求。
什么是构造函数和析构函数?它们的作用是什么?
- 构造函数:
- 解释:构造函数是一种特殊的成员函数,它的名称与类名相同,没有返回类型。构造函数在对象创建时自动被调用,用于初始化对象的成员变量。
- 作用:构造函数的主要作用是在对象创建时为对象分配内存,并对对象的成员变量进行初始化。构造函数可以有多个重载形式,以满足不同的初始化需求。通过构造函数,可以确保对象在创建时处于一个合法的状态。
- 析构函数:
- 解释:析构函数也是一种特殊的成员函数,它的名称是在类名前加上波浪线(~),没有返回类型和参数。析构函数在对象销毁时自动被调用,用于释放对象占用的资源。
- 作用:析构函数的主要作用是在对象销毁时释放对象占用的资源,如动态分配的内存、打开的文件等。析构函数可以确保对象在销毁时不会留下任何资源泄漏或未释放的资源。当对象超出作用域或被显式删除时,析构函数会自动被调用。