当前位置: 首页 > news >正文

【C++篇】栈的层叠与队列的流动:在 STL 的韵律中探寻数据结构的优雅之舞

在这里插入图片描述

文章目录

  • C++ 栈与队列详解:基础与进阶应用
    • 前言
    • 第一章:栈的介绍与使用
      • 1.1 栈的介绍
      • 1.2 栈的使用
        • 1.2.1 最小栈
        • 1.2.2 示例与输出
      • 1.3 栈的模拟实现
    • 第二章:队列的介绍与使用
      • 2.1 队列的介绍
      • 2.2 队列的使用
        • 2.2.1 示例与输出
      • 2.3 队列的模拟实现
        • 2.3.1 示例与输出
    • 第三章:优先队列的介绍与使用
      • 3.1 优先队列的介绍
      • 3.2 优先队列的使用
        • 3.2.1 示例:默认大顶堆
        • 3.2.2 示例与输出
        • 3.2.3 示例:小顶堆
      • 3.3 优先队列的模拟实现
        • 3.3.1 示例与输出
    • 第四章:容器适配器
      • 4.1 什么是容器适配器
      • 4.2 deque 的简单介绍
        • 4.2.1 deque 的原理介绍
        • 4.2.2 deque 的缺陷
        • 4.2.3 deque 的常见操作
      • 4.3 为什么选择 deque 作为 stack 和 queue 的底层默认容器
      • 4.4 STL 标准库中 stack 和 queue 的模拟实现
        • 4.4.1 stack 的模拟实现
        • 4.4.2 queue 的模拟实现
    • 第五章:总结
      • 5.1 核心要点回顾

C++ 栈与队列详解:基础与进阶应用

💬 欢迎讨论:在学习过程中,如果有任何疑问或想法,欢迎在评论区留言一起讨论。

👍 点赞、收藏与分享:觉得这篇文章对你有帮助吗?记得点赞、收藏并分享给更多的朋友吧!你们的支持是我不断进步的动力!
🚀 分享给更多人:如果你觉得这篇文章对你有帮助,欢迎分享给更多对 C++ 感兴趣的朋友,一起学习进步!


前言

栈与队列是常见的数据结构,常被用于不同的算法场景。在本文中,我们将详细探讨栈与队列的基本概念、实际应用及其模拟实现。栈和队列在日常开发中的重要性不言而喻,通过对这两种数据结构的深入理解,将助你更加灵活地应对算法题目和工程开发。

在阅读本篇之前,可以先看看stl最基础的部分:

【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
【C++篇】从零实现 C++ Vector:深度剖析 STL 的核心机制与优化


第一章:栈的介绍与使用

1.1 栈的介绍

栈 (Stack) 是一种 后进先出 (LIFO, Last In First Out) 的数据结构。这意味着栈中最后一个被插入的元素会第一个被移出。这种特性使得栈在实现某些算法时非常有用,例如函数调用栈、表达式求值以及括号匹配等。

栈提供的基本操作包括:

  • push():将元素压入栈顶。
  • pop():将栈顶元素弹出。
  • top():获取栈顶元素。
  • empty():检查栈是否为空。
  • size():获取栈中元素的数量。

常见的栈使用场景有表达式求值、深度优先搜索(DFS)以及回溯法。

1.2 栈的使用

1.2.1 最小栈

最小栈 (Min Stack) 是栈的扩展应用,除了提供基本的栈操作外,还能够在常量时间内返回栈中的最小值。下面展示一个最小栈的具体实现。

#include <stack>
using namespace std;class MinStack {
public:// 构造函数MinStack() {}// 将元素 x 压入栈中void push(int x) {    _elem.push(x);  // 元素入栈if (_min.empty() || x <= _min.top()) {  _min.push(x);  // 如果 x 小于等于当前最小值,则将 x 也压入 _min 栈}}// 移除栈顶元素void pop() {if (_min.top() == _elem.top()) {_min.pop();  // 如果当前栈顶元素是最小值,将其从 _min 栈中移除}_elem.pop();}// 获取栈顶元素int top() { return _elem.top(); }// 获取当前栈中的最小值int getMin() { return _min.top(); }private:stack<int> _elem;  // 存储栈中的所有元素stack<int> _min;   // 存储栈中的最小值
};
1.2.2 示例与输出
int main() {MinStack minStack;minStack.push(-2);minStack.push(0);minStack.push(-3);cout << "Current Min: " << minStack.getMin() << endl;  // 输出 -3minStack.pop();cout << "Top: " << minStack.top() << endl;             // 输出 0cout << "Current Min: " << minStack.getMin() << endl;  // 输出 -2return 0;
}

输出结果

Current Min: -3
Top: 0
Current Min: -2

在这个例子中,我们实现了一个最小栈,可以在常量时间内获取栈中的最小值。在压栈和弹栈操作时,我们同步更新 _min 栈以维护最小值。


1.3 栈的模拟实现

栈的标准实现使用 std::stack 容器,但在某些场景下,可以使用 std::vector 来模拟栈的功能。由于栈的所有操作都围绕末端进行,因此 vector 的尾插操作与 stack 类似。

#include <vector>
using namespace std;template <typename T>
class SimulatedStack {
public:// 向栈中压入元素void push(const T& x) {_data.push_back(x);}// 弹出栈顶元素void pop() {_data.pop_back();}// 获取栈顶元素T& top() {return _data.back();}// 检查栈是否为空bool empty() const {return _data.empty();}// 获取栈的大小size_t size() const {return _data.size();}private:vector<T> _data;  // 用于存储栈元素的容器
};

这种模拟实现使用了 vector 的尾插操作,可以高效地模拟栈的行为。


第二章:队列的介绍与使用

2.1 队列的介绍

队列 (Queue) 是一种 先进先出 (FIFO, First In First Out) 的数据结构。这意味着第一个进入队列的元素会第一个被移出。队列通常用于任务调度、广度优先搜索 (BFS) 等场景。

队列的基本操作包括:

  • push():将元素插入队尾。
  • pop():移除队头元素。
  • front():获取队头元素。
  • back():获取队尾元素。
  • empty():检查队列是否为空。
  • size():获取队列中的元素数量。

2.2 队列的使用

以下是队列的基本用法展示,包括插入和删除元素。

#include <queue>
#include <iostream>
using namespace std;int main() {queue<int> q;q.push(1);  // 向队尾插入元素1q.push(2);  // 向队尾插入元素2cout << "Front: " << q.front() << endl;  // 输出队头元素 1cout << "Back: " << q.back() << endl;    // 输出队尾元素 2q.pop();  // 移除队头元素cout << "After pop, Front: " << q.front() << endl;  // 输出新的队头元素 2return 0;
}
2.2.1 示例与输出

输出结果

Front: 1
Back: 2
After pop, Front: 2

在这个例子中,我们展示了队列的 push()pop()front()back() 操作。


2.3 队列的模拟实现

在一些场景中,标准库中的 std::queue 可能无法满足特定需求,我们可以通过其他容器类来模拟实现队列。由于队列需要支持在头部删除和尾部插入的操作,使用 std::list 会比 std::vector 更为高效。list 允许在常数时间内进行头部和尾部的插入与删除操作,因此非常适合用于队列的实现。

下面是一个基于 list 的队列模拟实现:

#include <list>
using namespace std;template <typename T>
class SimulatedQueue {
public:// 向队尾插入元素void push(const T& x) {_data.push_back(x);}// 移除队头元素void pop() {_data.pop_front();}// 获取队头元素T& front() {return _data.front();}// 获取队尾元素T& back() {return _data.back();}// 检查队列是否为空bool empty() const {return _data.empty();}// 获取队列的大小size_t size() const {return _data.size();}private:list<T> _data;  // 用于存储队列元素的容器
};
2.3.1 示例与输出
int main() {SimulatedQueue<int> q;q.push(10);  // 向队尾插入元素q.push(20);cout << "队头: " << q.front() << endl;  // 输出队头元素 10cout << "队尾: " << q.back() << endl;  // 输出队尾元素 20q.pop();  // 移除队头元素cout << "新的队头: " << q.front() << endl;  // 输出新的队头元素 20return 0;
}

输出结果

队头: 10
队尾: 20
新的队头: 20

在这个例子中,SimulatedQueue 模拟了队列的基本功能,包括在队尾插入元素和移除队头元素。


第三章:优先队列的介绍与使用

3.1 优先队列的介绍

优先队列 (Priority Queue) 是一种特殊类型的队列,其中每个元素都关联有一个优先级。优先队列的特点是元素的弹出顺序不再是按照先进先出,而是按照元素的优先级来决定。通常优先队列可以用来模拟堆结构。

在默认情况下,C++ 标准库中的 std::priority_queue 是一个大顶堆,即优先队列中的最大元素会优先弹出。我们也可以通过自定义比较函数来实现小顶堆,从而使得最小元素优先弹出。

优先队列的常见操作包括:

  • push():向优先队列中插入元素。
  • pop():移除优先级最高的元素。
  • top():获取优先级最高的元素。
  • empty():检查优先队列是否为空。
  • size():获取优先队列中的元素数量。

3.2 优先队列的使用

下面展示了如何使用 std::priority_queue 进行优先队列操作。

3.2.1 示例:默认大顶堆
#include <iostream>
#include <queue>
#include <vector>
using namespace std;int main() {priority_queue<int> pq;  // 默认大顶堆pq.push(10);pq.push(5);pq.push(20);cout << "优先级最高的元素: " << pq.top() << endl;  // 输出 20pq.pop();  // 移除优先级最高的元素cout << "新的优先级最高的元素: " << pq.top() << endl;  // 输出 10return 0;
}
3.2.2 示例与输出

输出结果

优先级最高的元素: 20
新的优先级最高的元素: 10

在这个例子中,priority_queue<int> 实现了一个大顶堆,插入元素后,优先级最高的元素(值最大的元素)会优先弹出。

3.2.3 示例:小顶堆

我们也可以使用 std::greater<T> 来改变默认的比较方式,从而实现小顶堆。下面是一个小顶堆的例子:

#include <iostream>
#include <queue>
#include <vector>
using namespace std;int main() {priority_queue<int, vector<int>, greater<int>> pq;  // 小顶堆pq.push(10);pq.push(5);pq.push(20);cout << "优先级最高的元素(最小值): " << pq.top() << endl;  // 输出 5pq.pop();  // 移除优先级最高的元素cout << "新的优先级最高的元素: " << pq.top() << endl;  // 输出 10return 0;
}

输出结果

优先级最高的元素(最小值): 5
新的优先级最高的元素: 10

在这个例子中,priority_queue<int, vector<int>, greater<int>> 实现了一个小顶堆,其中优先级最高的元素是值最小的元素。


3.3 优先队列的模拟实现

优先队列通常是基于堆实现的。在 C++ 中,标准库中的 priority_queue 使用 std::vector 作为底层存储,并通过堆算法管理优先级。在需要自定义优先队列行为时,可以自己实现一个简单的优先队列,利用堆的概念来操作。

下面是一个基于 std::vector 实现的简单优先队列:

#pragma once#include <iostream>
#include <vector>
using namespace std;// priority_queue--->堆
namespace W {// 默认的比较函数为 less,实现大顶堆template<class T>struct less {bool operator()(const T& left, const T& right) {return left < right;}};// greater 实现小顶堆template<class T>struct greater {bool operator()(const T& left, const T& right) {return left > right;}};template<class T, class Container = std::vector<T>, class Compare = less<T>>class priority_queue {public:// 创造空的优先级队列priority_queue() : c() {}// 构造函数支持从迭代器范围初始化template<class Iterator>priority_queue(Iterator first, Iterator last): c(first, last) {// 将 c 中的元素调整成堆的结构int count = c.size();int root = ((count - 2) >> 1);for (; root >= 0; root--)AdjustDown(root);}// 向队列中插入元素void push(const T& data) {c.push_back(data);AdjustUP(c.size() - 1);}// 移除优先级最高的元素void pop() {if (empty())return;swap(c.front(), c.back());c.pop_back();AdjustDown(0);}// 获取优先队列的大小size_t size() const {return c.size();}// 检查优先队列是否为空bool empty() const {return c.empty();}// 返回优先级最高的元素(不允许修改)const T& top() const {return c.front();}private:// 向上调整,维护堆的性质void AdjustUP(int child) {// 计算父节点的索引,等同于 (child - 1) / 2,移位操作符效率更快int parent = ((child - 1) >> 1);while (child) {if (Compare()(c[parent], c[child])) {swap(c[child], c[parent]);child = parent;parent = ((child - 1) >> 1);} else {return;}}}// 向下调整,维护堆的性质void AdjustDown(int parent) {size_t child = parent * 2 + 1;while (child < c.size()) {// 找到父节点较大的孩子if (child + 1 < c.size() && Compare()(c[child], c[child + 1])) {child += 1;}// 检查双亲是否满足堆的条件if (Compare()(c[parent], c[child])) {swap(c[child], c[parent]);parent = child;child = parent * 2 + 1;} else {return;}}}private:Container c;  // 底层容器,默认为 vector};
}

3.3.1 示例与输出
void TestQueuePriority() {W::priority_queue<int> q1;// 向大顶堆中插入元素q1.push(5);q1.push(1);q1.push(4);q1.push(2);q1.push(3);q1.push(6);// 输出堆顶元素cout << "优先级最高的元素: " << q1.top() << endl;  // 输出 6// 弹出两个元素q1.pop();q1.pop();// 再次输出堆顶元素cout << "新的优先级最高的元素: " << q1.top() << endl;  // 输出 4// 使用 greater 创建小顶堆vector<int> v{5, 1, 4, 2, 3, 6};W::priority_queue<int, vector<int>, W::greater<int>> q2(v.begin(), v.end());// 输出小顶堆的堆顶元素cout << "优先级最高的元素(最小值): " << q2.top() << endl;  // 输出 1// 弹出两个元素q2.pop();q2.pop();// 再次输出小顶堆的堆顶元素cout << "新的优先级最高的元素(最小值): " << q2.top() << endl;  // 输出 3
}

输出结果:

优先级最高的元素: 6
新的优先级最高的元素: 4
优先级最高的元素(最小值): 1
新的优先级最高的元素(最小值): 3

在这个模拟实现中,我们使用 std::vector 作为底层容器,并且通过堆排序算法来维护优先队列的顺序。通过 lessgreater 函数对象,我们可以分别实现大顶堆和小顶堆。


第四章:容器适配器

4.1 什么是容器适配器

容器适配器 (Container Adapter) 是一种设计模式,目的是将一种容器包装为另一种接口形式。容器适配器提供了一组特定的成员函数来访问底层的容器。C++ 标准库中,stackqueuepriority_queue 都是容器适配器,它们对容器的操作进行了限制,并定义了特定的访问规则。

在这里插入图片描述

容器适配器本质上是对基础容器的封装,它们可以使用 vectordequelist 等作为底层实现,而具体使用哪种容器可以根据需求进行调整。容器适配器只暴露了某些特定的操作,而底层容器的更多操作则被隐藏。

虽然stack和queue中也可以存放元素,但在STL中并没有将其划分在容器的行列,而是将其称为容器适配器,这是因为stack和队列只是对其他容器的接口进行了包装,STL中stack和queue默认使用deque

常见的容器适配器:

  • stack:实现后进先出(LIFO)原则。
    在这里插入图片描述

  • queue:实现先进先出(FIFO)原则。

在这里插入图片描述

  • priority_queue:基于优先级进行元素的弹出,通常是大顶堆。
    在这里插入图片描述

4.2 deque 的简单介绍

双端队列 (deque, Double-Ended Queue) 是一种可以在头尾两端进行高效插入和删除操作的序列式容器。与 vector 类似,deque 提供了动态数组的功能,但它比 vector 更加灵活,允许在头尾两端都进行元素的添加和删除。

在这里插入图片描述

4.2.1 deque 的原理介绍
  • 双端操作deque 提供了双端操作,即允许在容器的两端进行插入和删除操作。其时间复杂度为常数时间 O ( 1 ) O(1) O(1),这使得它比 vector 更适合需要频繁在两端插入或删除元素的场景。
  • 非连续存储:虽然 deque 表面上看起来像是一个连续的数组,但它的底层实现并非真正连续,而是由多块小的连续内存块组合而成,这就允许 deque 在进行元素插入或删除时,不需要像 vector 一样移动大量元素。

下面是一张简化的 deque 的内存布局示意图:

--------------------------------
| Block 1 | Block 2 | Block 3  |
--------------------------------

每个块表示 deque 底层的一部分内存,插入或删除元素时,只需要操作相应块中的数据,而不需要重新分配整个数组的内存。

在这里插入图片描述

双端队列底层是一段假象的连续空间,实际是分段连续的,为了维护其“整体连续”以及随机访问
的假象,落在了deque的迭代器身上,因此deque的迭代器设计就比较复杂,如下图所示:

在这里插入图片描述

那deque是如何借助其迭代器维护其假想连续的结构呢?

在这里插入图片描述

了解一下即可


4.2.2 deque 的缺陷

虽然 deque 在插入和删除操作上比 vector 更高效,但它也有一些缺点:

  1. 遍历性能较低:由于 deque 的存储结构不是一个连续的内存块,所以在遍历 deque 时,迭代器需要处理内存块之间的跳转,导致遍历性能不如 vector
  2. 内存利用率稍低:因为 deque 是由多个小内存块组成的,所以它的内存利用率相比 vector 稍差。不过与 list 比较,deque 的内存效率还是更高。
4.2.3 deque 的常见操作
#include <deque>
#include <iostream>
using namespace std;int main() {deque<int> d;// 在队列的两端插入元素d.push_back(10);d.push_back(20);d.push_front(5);cout << "队头: " << d.front() << endl;  // 输出 5cout << "队尾: " << d.back() << endl;   // 输出 20// 删除队列的两端元素d.pop_front();d.pop_back();cout << "新的队头: " << d.front() << endl;  // 输出 10return 0;
}

输出结果

队头: 5
队尾: 20
新的队头: 10

这个示例展示了 deque 如何进行两端的插入和删除操作。可以看到,deque 支持同时在队头和队尾进行高效的操作。


4.3 为什么选择 deque 作为 stack 和 queue 的底层默认容器

C++ 标准库中,stackqueue 的底层容器默认使用 deque,这是因为 deque 在元素插入和删除时的性能优势以及空间利用率较高的特点,正好符合 stackqueue 对容器的需求。

  1. 高效的尾部插入和删除:对于 stack,只需要支持在容器的尾部插入和删除元素,dequepush_back()pop_back() 操作可以在常数时间内完成,比 vector 在扩容时效率更高。
  2. 高效的头部插入和删除:对于 queue,需要在尾部插入元素、在头部删除元素,deque 同时支持 push_back()pop_front() 操作,效率比 list 高,且不需要存储额外的指针信息。

虽然 vector 也可以作为 stack 的底层容器,但它在尾部插入元素时需要在扩容时移动大量元素,因此效率不如 deque。而 list 虽然也支持两端插入删除操作,但由于需要存储额外的指针信息,空间利用率不如 deque 高。因此,deque 被认为是 stackqueue 的默认最佳选择。


4.4 STL 标准库中 stack 和 queue 的模拟实现

4.4.1 stack 的模拟实现

stack 的模拟实现只需要封装一个可以支持末端插入和删除操作的容器,默认情况下,使用 deque 作为底层容器。

#include <deque>namespace W {template <typename T, typename Container = deque<T>>
class stack {
public:stack() {}// 向栈中压入元素void push(const T& x) {_c.push_back(x);}// 弹出栈顶元素void pop() {_c.pop_back();}// 获取栈顶元素T& top() {return _c.back();}// 检查栈是否为空bool empty() const {return _c.empty();}// 获取栈的大小size_t size() const {return _c.size();}private:Container _c;  // 底层容器,默认使用 deque
};
}
4.4.2 queue 的模拟实现

queue 的实现需要支持队尾插入元素、队头删除元素的操作。类似 stackqueue 默认使用 deque 作为底层容器。

#include <deque>namespace W {template <typename T, typename Container = deque<T>>
class queue {
public:queue() {}// 向队尾插入元素void push(const T& x) {_c.push_back(x);}// 移除队头元素void pop() {_c.pop_front();}// 获取队头元素T& front() {return _c.front();}// 获取队尾元素T& back() {return _c.back();}// 检查队列是否为空bool empty() const {return _c.empty();}// 获取队列的大小size_t size() const {return _c.size();}private:Container _c;  // 底层容器,默认使用 deque
};
}

第五章:总结

在本文中,我们详细探讨了 栈 (stack)队列 (queue) 的概念、应用及其实现方式。通过对 dequepriority _queue 的深入理解,我们可以更高效地解决实际编程问题。

5.1 核心要点回顾

  • 栈是一种后进先出的数据结构,常用于表达式求值、函数调用栈等。
  • 队列是一种先进先出的数据结构,广泛应用于任务调度、广度优先搜索等场景。
  • 优先队列根据元素的优先级进行排序,常用于调度和路径优化算法。
  • deque 作为双端队列,支持在头尾两端进行高效的插入和删除操作。
  • 容器适配器 stackqueue 使用 deque 作为底层容器,利用其高效的插入删除操作实现栈和队列的功能。

通过对这些数据结构的深入理解,我们能够在编程中更加灵活、准确地选择合适的工具来解决实际问题。

💬 讨论区:如果你有任何问题,欢迎在评论区留言讨论!
👍 支持一下:如果你觉得这篇文章对你有帮助,请点赞、收藏并分享给更多学习者!


以上就是关于【C++篇】栈的层叠与队列的流动:在 STL 的韵律中探寻数据结构的优雅之舞的内容啦,各位大佬有什么问题欢迎在评论区指正,或者私信我也是可以的啦,您的支持是我创作的最大动力!❤️

在这里插入图片描述

相关文章:

【C++篇】栈的层叠与队列的流动:在 STL 的韵律中探寻数据结构的优雅之舞

文章目录 C 栈与队列详解&#xff1a;基础与进阶应用前言第一章&#xff1a;栈的介绍与使用1.1 栈的介绍1.2 栈的使用1.2.1 最小栈1.2.2 示例与输出 1.3 栈的模拟实现 第二章&#xff1a;队列的介绍与使用2.1 队列的介绍2.2 队列的使用2.2.1 示例与输出 2.3 队列的模拟实现2.3.…...

使用 Flask 实现简单的登录注册功能

目录 1. 引言 2. 环境准备 3. 数据库设置 4. Flask 应用基本配置 5. 实现用户注册 6. 实现用户登录 7. 路由配置 8. 创建前端页面 9. 结论 1. 引言 在这篇文章中&#xff0c;我们将使用 Flask 框架创建一个简单的登录和注册系统。Flask 是一个轻量级的 Python Web 框架…...

计算机毕业设计Python+大模型微博情感分析 微博舆情预测 微博爬虫 微博大数据 舆情分析系统 大数据毕业设计 NLP文本分类 机器学习 深度学习 AI

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 《Python大模型微博情感分析…...

CTF--Misc题型小结

&#xff08;萌新笔记&#xff0c;多多关照&#xff0c;不足之处请及时提出。&#xff09; 不定时更新~ 目录 密码学相关 文件类型判断 file命令 文件头类型 strings读取 隐写术 尺寸修改 文件头等缺失 EXIF隐写 thumbnail 隐写 文件分离&提取 binwalk foremo…...

深度学习系列——RNN/LSTM/GRU,seq2seq/attention机制

1、RNN/LSTM/GRU可参考&#xff1a; https://zhuanlan.zhihu.com/p/636756912 &#xff08;1&#xff09;对于这里面RNN的表示中&#xff0c;使用了输入x和h的拼接描述&#xff0c;其他公式中也是如此 &#xff08;2&#xff09;各符号图含义如下 2、关于RNN细节&#xff0c;…...

通过call指令来学习指令摘要表的细节

E8 cw cw 表示E8后面跟随2 字节 (什么数不知道) rel16 指在与指令同一代码段内的相对地址偏移 D ,指向Instruction Operand Encoding 表中的D列, 他告诉我们 操作数1 是一个0FFSET N.S. 在64位模式下&#xff0c;某些指令需要使用“地址覆盖前缀”&#xff08;address over…...

10分钟使用Strapi(无头CMS)生成基于Node.js的API接口,告别繁琐开发,保姆级教程,持续更新中。

一、什么是Strapi&#xff1f; Strapi 是一个开源的无头&#xff08;headless&#xff09; CMS&#xff0c;开发者可以自由选择他们喜欢的开发工具和框架&#xff0c;内容编辑人员使用自有的应用程序来管理和分发他们的内容。得益于插件系统&#xff0c;Strapi 是一个灵活的 C…...

创建插件 DLL 项目

Step 1: 创建插件 DLL 项目 在 Visual Studio 中创建一个新的 DLL 项目&#xff0c;并添加以下文件和代码。 头文件&#xff1a;CShapeBase.h cpp 复制代码 #pragma once #include <afxwin.h> // MFC 必需头文件 #include <string> #include <vector> #i…...

OpenCV双目相机外参标定C++

基于OpenCV库实现双目测量系统外参标定过程。通过分析双目测量系统左右相机拍摄的棋盘格标定板图像&#xff0c;包括角点检测、立体标定、立体校正和畸变校正的步骤&#xff0c;获取左右相机的相对位置关系和姿态。 a.检测每张图像中的棋盘格角点&#xff0c;并进行亚像素级精…...

【GESP】C++一级练习BCQM3055,4位数间隔输出

一级知识点取余、整除运算和格式化输出知识点应用。其实也可以用string去处理&#xff0c;那就属于GESP三级的知识点范畴了&#xff0c;孩子暂未涉及。 题目题解详见&#xff1a;https://www.coderli.com/gesp-1-bcqm3055/ https://www.coderli.com/gesp-1-bcqm3055/https://w…...

纯血鸿蒙的最难时刻才开始

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 纯血鸿蒙(HarmonyOS NEXT)也正式发布了&#xff0c;绝对是一个历史性时刻&#xff0c;但最难的鸿蒙第二个阶段&#xff0c;也就是生态圈的建设&#xff0c;才刚刚开始。 目前&#xff0c;我劝你现在不要升级到鸿蒙…...

记一个mysql的坑

数据库表user&#xff0c; 存在一个name字段&#xff0c;字段为varchar类型 现在user表有这么两条记录: idnameageclass1NULL18一班2lisi20二班 假如我根据下面这一条件去更新&#xff0c;更新成功数据行显示为0 update user set age 19 where age 18 and class “一班”…...

Java中的设计模式:单例模式详解

摘要 单例模式&#xff08;Singleton Pattern&#xff09;是Java中最常用的设计模式之一&#xff0c;属于创建型模式。它的主要目的是确保一个类在系统中只有一个实例&#xff0c;并提供一个全局访问点来访问该实例。 1. 单例模式的定义 单例模式确保一个类只有一个实例&…...

NanoTrack原理与转tensorrt推理

文章目录 前言一、NanoTrack 工作原理二、运行demo与转换tensorrt模型2.1 运行pt模型demo2.2 转onnx模型2.3 转tensorrt模型2.4 运行trt模型推理 三、推理速度对比总结 前言 NanoTrack 是一种轻量级且高效的目标跟踪算法&#xff0c;基于Siamese网络架构&#xff0c;旨在在资源…...

YOLO11改进 | 卷积模块 | 卷积模块替换为选择性内核SKConv【附完整代码一键运行】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 本文给大家带来的教程是将YOLO11的卷积替…...

CentOS进入单用户模式进行密码重置

一、单用户模式介绍 单用户模式是一种特殊的启动模式&#xff0c;主要用于系统维护和故障排除。在单用户模式下&#xff0c;系统以最小化的状态启动&#xff0c;只有最基本的系统服务会被加载&#xff0c;通常只有root用户可以登录。这种模式提供了对系统的完全控制&#xff0…...

bitpoke- mysql-operator cluster

sidecar版本只支持到8.0.35&#xff0c;35可以支持到mysql8.0.35 . 默认镜像是5.7的。需要自己打sidecar的镜像&#xff1a; # Docker image for sidecar containers # https://github.com/bitpoke/mysql-operator/tree/master/images/mysql-operator-sidecar-8.0 # 参考5…...

第5课 基本数据类型

一、数据类型的诞生 在Python的世界里&#xff0c;万物皆对象&#xff0c;每个对象都有自己的若干属性&#xff0c;每一个属性都能描述对象的某一个方面。就像我们每个人&#xff0c;都有自己的身高、年龄、姓名、性别等很多方面的信息&#xff0c;这里的身高、年龄、姓名、性…...

OceanBase 首席科学家阳振坤:大模型时代的数据库思考

2024年 OceanBase 年度大会 即将于10月23日&#xff0c;在北京举行。 欢迎到现场了解更多“SQL AI ” 的探讨与分享&#xff01; 近期&#xff0c;2024年金融业数据库技术大会在北京圆满举行&#xff0c;聚焦“大模型时代下数据库的创新发展”议题&#xff0c;汇聚了国内外众多…...

国内知名的几个镜像源

在国内&#xff0c;有许多常用的Python库镜像源可以帮助加速库的下载。以下是几个知名的镜像源&#xff1a; 1. 清华大学TUNA协会 网址: https://pypi.tuna.tsinghua.edu.cn/simple命令示例:pip install numpy --index-url https://pypi.tuna.tsinghua.edu.cn/simple2. 阿里云…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档&#xff1a;https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java&#xff08;供 Kotlin 使用&#xff09; 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...