C++ 复习总结记录十

C++ 复习总结记录十

主要内容

1、stack 介绍和使用

2、queue 介绍和使用

3、priority_queue 介绍和使用

4、容器适配器

一 stack 的介绍和使用

stack 文档介绍

1、 stack 是容器适配器,专用于后进先出的操作,只能从容器尾端进行元素插入和提取

2、 容器适配器是对特定类封装作为底层容器,并提供一组特定的成员函数

3、 stack 底层容器可以是任何标准的容器类模板或一些其他特定的容器类,这些容器类应支持以下操作

  • empty 判空操作
  • back 获取尾部元素操作
  • push_back 尾部插入元素操作
  • pop_back 尾部删除元素操作

4、标准容器 vector、deque、list 均符合上述需求,stack 的默认底层容器是 deque

image-20250124112549918

1.1 stack 的使用

函数说明 						接口说明
stack() 					构造空的栈
empty() 					检测 stack 是否为空
size() 						返回 stack 中元素的个数
top() 						返回栈顶元素的引用
push() 						将元素 val 压入 stack 中
pop() 						将 stack 中尾部的元素弹出

1.2 练习

最小栈

class MinStack {
public:
    MinStack() {}
    
    void push(int val) 
    {
        if(minStack.size() == 0 || val <= minStack.top()) //若最小栈为空或插入数据小于或等于栈顶元素
            minStack.push(val); //入最小栈
        src.push(val); //所有数据栈, 则直接入栈
    }
    
    void pop() 
    {
        if(minStack.size() != 0 && src.top() == minStack.top()) //若最小栈不为空且删除数据所有数据栈顶元素等于最小栈顶元素
            minStack.pop(); //删除最小栈顶元素
        src.pop(); //所有数据栈, 则直接删除栈顶元素
    }
    
    int top() 
    {
        return src.top(); //返回所有数据栈顶元素
    }
    
    int getMin() 
    {
        return minStack.top(); //返回最小栈顶元素
    }
    
private:
    stack<int> src; //所有数据的栈
    stack<int> minStack; //最小栈
};

栈的弹出压入序列

bool IsPopOrder(vector<int>& pushV, vector<int>& popV) 
{
    stack<int> data; //data 模拟进出栈过程
    int p1 = 0, p2 = 0; //p1, p2 是对用 vector 的下标

    while(p1 < pushV.size()) //入栈顺序数据不为空
    {
        data.push(pushV[p1]); //直接入栈
        while (p2 < popV.size() && 
               data.size() !=0 && 
               data.top() == popV[p2]) //判断栈顶元素是否和出栈数据相同(注意边界条件)
        {
            data.pop(); //出栈
            ++p2; //移动下标
        }
        ++p1; //移动下标
    }
    return data.size() == 0; //校验栈内是否还有数据
}

逆波兰表达式求值

int evalRPN(vector<string>& tokens) {
    stack<int> ans;
    int left = 0, right = 0;
    for (auto& str : tokens)
    {
        if (!("+" == str || "-" == str || "*" == str || "/" == str)) //注意这里的判断条件不能用 str[0] >= '0', 因为可能有负数
        {
            ans.push(stoi(str)); //C++11, C 风格转换 atoi(str.c_str());
        }
        else
        {
            right = ans.top(); //注意这里栈顶元素是右操作数
            ans.pop();
            left = ans.top();
            ans.pop();

            switch(str[0])
            {
                case '+':
                    ans.push(left + right);
                    break;
                case '-':
                    ans.push(left - right);
                    break;
                case '*':
                    ans.push(left * right);
                    break;
                case '/':
                    ans.push(left / right);
                    break;
            }
        }            
    }
    return ans.top();
}

用两个栈实现队列

class MyQueue {
public:
    MyQueue() {}
    
    void push(int x) 
    {
        s1.push(x);
    }
    
    int pop() 
    {
        int res = peek();
        s2.pop();
        return res;
    }
    
    int peek() 
    {
        if (s2.size() == 0) //若 s2 为空, 需要把 s1 数据搬至 s2
        {
            while(s1.empty())
            {
                s2.push(s1.top());
                s1.pop();
            }
        }
        return s2.top();  //s2 栈顶元素即为队列头元素
    }
    
    bool empty() 
    {
        return s1.size() == 0 && s2.size() == 0;
    }

private:
    stack<int> s1;
    stack<int> s2;
};

1.3 stack 模拟实现

使用 vector 模拟实现 stack

#include<vector>
namespace lucky
{
    template<class T>
    class stack
    {
    public:
        stack() {}
        
        void push(const T& x) {_c.push_back(x);}
        
        void pop() {_c.pop_back();}
        
        T& top() {return _c.back();}
        
        const T& top()const {return _c.back();}
        
        size_t size()const {return _c.size();}
        
        bool empty()const {return _c.empty();}
        
    private:
        std::vector<T> _c;
    };
}

二 queue 的介绍和使用

queue 文档介绍

1、队列是一种容器适配器,用于 FIFO ( 先进先出 ) 操作,从容器一端插入元素,另一端提取元素

2、底层容器可以是标准容器类模板之一,也可是其它专门设计的容器类。该底层容器应至少支持以下操作

  • empty 检测队列是否为空
  • size 返回队列中有效元素个数
  • front 返回队头元素引用
  • back 返回队尾元素引用
  • push_back 在队列尾部入队列
  • pop_front 在队列头部出队列

4、标准容器类 deque 和 list 满足了这些要求。默认情况下 queue 指定使用标准容器 deque

image-20250124140046765

2.1 queue 的使用

函数声明 					接口说明
queue() 			构造空的队列
empty() 			检测队列是否为空, 是返回 true, 否则返回 false
size() 				返回队列中有效元素的个数
front() 			返回队头元素的引用
back() 				返回队尾元素的引用
push() 				在队尾将元素 val 入队列
pop() 				将队头元素出队列

用队列实现栈

class MyStack {
public:
    MyStack() {}
    
    void push(int x) 
    {
        q2.push(x); //元素先入 q2
        while(!q1.empty()) //若 q1 不为空, 拷 q1 数据至 q2
        {
            q2.push(q1.front()); //将 q1 首元素拷至 q2
            q1.pop(); //删除队列首元素
        }
        q1.swap(q2); //数据交换
    }
  
    int pop() 
    {
        int res = q1.front();
        q1.pop(); //删除 q1 队列首元素
        return res;
    }
    
    int top() { return q1.front(); }
    
    bool empty() { return q1.empty(); }

private:
    queue<int> q1;
    queue<int> q2;
};

2.2 queue 模拟实现

queue 接口中存在头删和尾插,使用 vector 封装效率太低,借助 list 模拟实现 queue

#include <list>
namespace lucky
{
    template<class T>
    class queue
    {
    public:
        queue() {}
        
        void push(const T& x) { _c.push_back(x); }
        
        void pop() { _c.pop_front(); }
        
        T& back() { return _c.back(); }
        
        const T& back() const { return _c.back(); }
        
        T& front() { return _c.front(); }

        const T& front() const { return _c.front(); }
        
        size_t size() const { return _c.size(); }
        
        bool empty() const { return _c.empty(); }
        
    private:
        std::list<T> _c;
    };
}

三 priority_queue 的介绍和使用

priority_queue 文档介绍

1、优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的

2、数据结构类似于堆,在堆中可以随时插入元素,并且只能检索最大堆元素 ( 优先队列中位于顶部的元素 )

3、底层容器可以是任何标准容器类模板,也可以是其他特定设计的容器类。容器应该可以通过随机访问迭代器访问,并支持以下操作

  • empty() 检测容器是否为空
  • size() 返回容器中有效元素个数
  • front() 返回容器中第一个元素的引用
  • push_back() 在容器尾部插入元素
  • pop_back() 删除容器尾部元素

4、标准容器类 vector 和 deque 满足上述需求;默认情况下,priority_queue 类实例化的容器类是 vector

5、需要支持随机访问迭代器,以便始终在内部保持堆结构。容器适配器通过在需要时自动调用算法函数 make_heap、push_heap 和 pop_heap 来自动完成此操作

3.1 priority_queue 的使用

优先级队列默认使用 vector 作为其底层存储数据的容器,在 vector 上又使用了堆算法将 vector 中元素构造成堆结构。

因此 priority_queue 就是堆,所有需要用到堆的位置,都可以考虑使用priority_queue,注意:默认情况下 priority_queue 是大堆

函数声明 					接口说明
priority_queue() 		构造一个空的优先级队列
priority_queue(first,last)  构造一个优先级队列
empty() 		检测优先级队列是否为空, 是返回 true, 否则返回 false
top() 			返回优先级队列中最大(最小元素),即堆顶元素
push(x) 		在优先级队列中插入元素 x
pop() 			删除优先级队列中最大(最小)元素,即堆顶元素

默认情况下,priority_queue 是大堆

#include <vector>
#include <queue>
#include <functional> // greater算法的头文件
void TestPriorityQueue()
{
    // 默认情况下, 创建的是大堆, 其底层按照小于号比较
    vector<int> v{3,2,7,6,0,4,1,9,8,5};
    priority_queue<int> q1;
    for (auto& e : v)
        q1.push(e);
    cout << q1.top() << endl;
    
    // 如果要创建小堆, 将第三个模板参数换成 greater 比较方式
    priority_queue<int, vector<int>, greater<int>> q2(v.begin(), v.end());
    cout << q2.top() << endl;
}

如果在 priority_queue 中放自定义类型数据,需在自定义类型中提供 > 或 < 重载

class Date
{
public:
    Date(int year = 1900, int month = 1, int day = 1)
        : _year(year)
            , _month(month)
            , _day(day)
        {}
    
    bool operator<(const Date& d) const
    {
        return (_year < d._year) ||
            (_year == d._year && _month < d._month) ||
            (_year == d._year && _month == d._month && _day < d._day);
    }
    
    bool operator>(const Date& d) const
    {
        return (_year > d._year) ||
            (_year == d._year && _month > d._month) ||
            (_year == d._year && _month == d._month && _day > d._day);
    }
    
    friend ostream& operator<<(ostream& _cout, const Date& d)
    {
        _cout << d._year << "-" << d._month << "-" << d._day;
        return _cout;
    }
    
private:
    int _year;
    int _month;
    int _day;
};

void TestPriorityQueue()
{
    // 大堆需要自定义类型中提供 < 重载
    priority_queue<Date> q1;
    q1.push(Date(2018, 10, 29));
    q1.push(Date(2018, 10, 28));
    q1.push(Date(2018, 10, 30));
    cout << q1.top() << endl;
    
    // 创建小堆提供 > 重载
    priority_queue<Date, vector<Date>, greater<Date>> q2;
    q2.push(Date(2018, 10, 29));
    q2.push(Date(2018, 10, 28));
    q2.push(Date(2018, 10, 30));
    cout << q2.top() << endl;
}

3.2 练习

数组中第 K 大的元素

方法一 最大堆 : 时间复杂度 N * logN,空间复杂度 log N

#include<functional>
int findKthLargest(vector<int>& nums, int k) {
    priority_queue<int, vector<int>, less<int>> p1(nums.begin(), nums.end()); //遍历时间复杂度 N, 调整最大堆时间复杂度 logN
    
    while (k-- > 1)
    {
    	p1.pop();
    }
    return p1.top();
}

方法二 排序 : 时间复杂度 N * logN,空间复杂度 O(1)

int findKthLargest(vector<int>& nums, int k) {
	sort(nums.begin(), nums.end());
    return nums[nums.size() - k];
}

方法三 最小堆 : 时间复杂度 N * logK,空间复杂度 logK

int findKthLargest(vector<int>& nums, int k) {
    priority_queue<int, vector<int>, greater<int>> p1(nums.begin(), nums.begin() + k);

    for (int i = k; i < nums.size(); ++i)
    {
        if (nums[i] > p1.top())
        {
            p1.pop();
            p1.push(nums[i]);
        }
    }
    return p1.top();
}

3.3 priority_queue 模拟实现

priority_queue 的底层结构就是堆,此处只需对其进行通用封装即可

#pragma once
#include <iostream>
using namespace std;

#include <vector>
// priority_queue ---> 堆
namespace lucky
{
	template<class T>
	struct less
	{
		bool operator()(const T& left, const T& right)
		{
			return left < right;
		}
	};

	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)
		{
			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())
			{
				// 找以 parent 为根的较大的孩子
				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;
	};
}

void TestQueuePriority()
{
	lucky::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;

	q1.pop();
	q1.pop();
	cout << q1.top() << endl;

	vector<int> v{ 5,1,4,2,3,6 };
	lucky::priority_queue<int, vector<int>, lucky::greater<int>> q2(v.begin(), v.end());
	cout << q2.top() << endl;

	q2.pop();
	q2.pop();
	cout << q2.top() << endl;
}

四 容器适配器

适配器是一种设计模式 ( 设计模式是一套被反复使用的、经过分类编目的、代码设计经验的总结),该种模式是将一个类接口转换成期望的另一个接口

image-20250124152438232

STL 标准库中 stack 和 queue 的底层结构

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

image-20250124152638179

image-20250124152704783

image-20250124152720624

4.1 deque 介绍

deque ( 双端队列 ),是一种双开口的连续空间数据结构,双开口含义是可以在头尾两端进行插入和删除操作,且时间复杂度为 O(1),与 vector 比较,头插效率高,不需要搬移元素;与 list 比较,支持随机访问且空间利用率比较高

image-20250124152918989

deque 并不是真正连续的空间,而是由一段段连续的小空间拼接而成的,实际 deque 类似于一个动态二维数组,其底层结构如下图所示

image-20250124153023654

双端队列的连续空间,实际是分段连续的,其整体连续以及随机访问的功能,主要因为 deque 的迭代器,设计如下

image-20250124153207756

image-20250124153234340

4.2 deque 缺陷

与 vector 相比,deque 优势是头部插入和删除时,不需要搬移元素,效率特别高且扩容时,也不需要搬移元素,效率 vector 高

与 list 相比,其底层是连续空间,空间利用率比较高,不需要存储额外字段

deque 的缺陷是不适合遍历,因为在遍历时,deque 迭代器要频繁的去检测其是否移动到某段小空间边界,导致效率低下。而序列式场景中,可能需要经常遍历,因此在大多数线性结构情况下,使用的是 vector 和 list,deque 应用并不多

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

stack 是一种后进先出的特殊线性数据结构,因此只要具有 push_back 和 pop_back 操作的线性结构,都可以作为 stack 的底层容器,比如 vector 和 list 等

queue 是先进先出的特殊线性数据结构,只要具有 push_back 和 pop_front 操作的线性结构,都可以作为 queue 的底层容器,比如 list 等

STL 中对 stack 和 queue 默认选择 deque 作为其底层容器,主要因为

① stack 和queue 不需要遍历 (因此 stack 和 queue 没有迭代器),只需要在固定的一端或者两端进行操作

② 在 stack 中元素增长时,deque 比 vector 的效率高 ( 扩容时不需要搬移大量数据 ) queue 中的元素增长时,deque 不仅效率高,且空间利用率高

4.4 STL 中对 stack 和 queue 模拟实现

stack 模拟实现

#include<deque>
namespace lucky
{
    template<class T, class Con = deque<T>>
    //template<class T, class Con = vector<T>>
    //template<class T, class Con = list<T>>
    class stack
    {
    public:
        stack() {}
        
        void push(const T& x) { _c.push_back(x); }
        
        void pop() { _c.pop_back(); }
        
        T& top() { return _c.back(); 1}
        
        const T& top() const {return _c.back();}
        
        size_t size() const {return _c.size();}
        
        bool empty() const {return _c.empty();}
        
    private:
        Con _c;
    };
}

queue 模拟实现

#include<deque>
#include <list>
namespace lucky
{
    template<class T, class Con = deque<T>>
    //template<class T, class Con = list<T>>
    class queue
    {
    public:
        queue() {}
        
        void push(const T& x) { _c.push_back(x); }
        
        void pop() { _c.pop_front(); }
        
        T& back() { return _c.back(); }
        
        const T& back() const { return _c.back(); }
        
        T& front() { return _c.front(); }
        
        const T& front() const { return _c.front(); }
        
        size_t size() const { return _c.size(); }
        
        bool empty() const { return _c.empty(); }
        
    private:
        Con _c;
    };
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/959252.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ESP32服务器和PC客户端的Wi-Fi通信

ESP32客户端-服务器Wi-Fi通信 本指南将向您展示如何设置ESP32板作为服务端&#xff0c;PC作为客户端&#xff0c;通过HTTP通信&#xff0c;以通过Wi-Fi&#xff08;无需路由器或互联网连接&#xff09;交换数据。简而言之&#xff0c;您将学习如何使用HTTP请求将一个板的数据发…

激光雷达和相机早期融合

通过外参和内参的标定将激光雷达的点云投影到图像上。 • 传感器标定 首先需要对激光雷达和相机&#xff08;用于获取 2D 图像&#xff09;进行外参和内参标定。这是为了确定激光雷达坐标系和相机坐标系之间的转换关系&#xff0c;包括旋转和平移。通常采用棋盘格等标定工具&…

机器学习-核函数(Kernel Function)

核函数&#xff08;Kernel Function&#xff09;是一种数学函数&#xff0c;主要用于将数据映射到一个更高维的特征空间&#xff0c;以便于在这个新特征空间中更容易找到数据的结构或模式。核函数的主要作用是在不需要显式计算高维特征空间的情况下&#xff0c;通过内积操作来实…

【基于无线电的数据通信链】Link 11 仿真测试

〇、废话 Link 11 仿真测试 涉及多个方面&#xff0c;包括信号仿真、协议模拟、数据链路层的仿真以及网络性能评估等。Link 11 是一种基于 HF&#xff08;高频&#xff09; 或 UHF&#xff08;超高频&#xff09; 波段的无线通信协议&#xff0c;主要用于军事通信系统中。为了…

计算机图形学:实验四 带纹理的OBJ文件读取和显示

一、程序功能设计 在程序中读取带纹理的obj文件&#xff0c;载入相应的纹理图片文件&#xff0c;将带纹理的模型显示在程序窗口中。实现带纹理的OBJ文件读取与显示功能&#xff0c;具体设计如下&#xff1a; OBJ文件解析与数据存储 通过实现TriMesh类中的readObj函数&#x…

【PVE】Proxmox VE8.0+创建LXC容器安装docker

为了不影响PVE宿主机&#xff0c;通常使用套娃的形式安装Docker容器&#xff0c;再安装相关docker应用。首先在CT模板中创建 Linux 容器&#xff0c;推荐使用Debian。开启ssh登录&#xff0c;修改debian配置&#xff0c;安装docker 一、创建 LXC 容器 1、CT模板下载 点击“模…

如何为64位LabVIEW配置正确的驱动程序

在安装 64位 LabVIEW 后&#xff0c;确保驱动程序正确配置是关键。如果您首先安装了 32位 LabVIEW 和相关驱动&#xff0c;然后安装了 64位 LabVIEW&#xff0c;需要确保为 64位 LabVIEW 安装和配置适当的驱动程序&#xff0c;才能正常访问硬件设备。以下是详细步骤&#xff1a…

MVCC底层原理实现

MVCC的实现原理 了解实现原理之前&#xff0c;先理解下面几个组件的内容 1、 当前读和快照读 先普及一下什么是当前读和快照读。 当前读&#xff1a;读取数据的最新版本&#xff0c;并对数据进行加锁。 例如&#xff1a;insert、update、delete、select for update、 sele…

设计模式-建造者模式、原型模式

目录 建造者模式 定义 类图 优缺点 角色 建造者模式和工厂模式比较 使用案例 原型模式 定义 类图 优缺点 应用场景 应用类型 浅克隆 深克隆 建造者模式 定义 将一个复杂的对象的构造与它的表示分离&#xff0c;使同样的构建过程可以创建不同的表示&#xff0c;…

Midscene.js:重新定义UI自动化的新时代工具

前言 Midscene.js 是一个创新的、面向开发者的 UI 自动化解决方案&#xff0c;并通过人工智能技术简化自动化脚本的编写与维护。 它提供了三种核心方法——交互&#xff08;.ai, .aiAction&#xff09;、提取&#xff08;.aiQuery&#xff09;和断言&#xff08;.aiAssert&am…

【落羽的落羽 数据结构篇】算法复杂度

文章目录 一、数据结构和算法简介二、算法复杂度1. 时间复杂度2. 空间复杂度 一、数据结构和算法简介 数据结构是计算机存储、组织数据的方式&#xff0c;指相互之间存在一种或多种特定关系的数据元素的集合。没有一种单一的数据结构对所有用途都有用&#xff0c;所以我们要学…

如何使用tushare pro获取股票数据——附爬虫代码以及tushare积分获取方式

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据 总结 一、Tushare 介绍 Tushare 是一个提供中国股市数据的API接口服务&#xff0c;它允许用户…

Java 实现Excel转HTML、或HTML转Excel

Excel是一种电子表格格式&#xff0c;广泛用于数据处理和分析&#xff0c;而HTM则是一种用于创建网页的标记语言。虽然两者在用途上存在差异&#xff0c;但有时我们需要将数据从一种格式转换为另一种格式&#xff0c;以便更好地利用和展示数据。本文将介绍如何通过 Java 实现 E…

迅为RK3568开发板篇OpenHarmony实操HDF驱动控制LED-添加内核编译

编译内核时将该 HDF 驱动编译到镜像中&#xff0c;接下来编写驱动编译脚本 Makefile&#xff0c;代码如下所示&#xff1a; 加入编译体系&#xff0c;填加模块目录到 drivers/hdf_core/adapter/khdf/linux/Makefile 文件 更多内容可以关注&#xff1a;迅为RK3568开发板篇OpenHa…

【含开题报告+文档+PPT+源码】基于SpringBoot的校园跑腿管理系统

开题报告 本文旨在探讨校园跑腿系统的设计与实现&#xff0c;通过深入研究与分析&#xff0c;实现了一套包含用户管理、发布跑腿单、跑腿抢单、跑腿单评论、在线留言以及用户在线充值等功能的综合性系统。该系统以提高校园内物品跑腿与配送效率为核心目标&#xff0c;为广大学…

|Python新手小白中级教程|第三十一章:日期与时间(time库使用指令——深化)——time库的9种常见函数【实用干货,一定要收藏!】

文章目录 前言导入一、基础函数&#xff1a;time.time() time.localtime() time.mktime()1.time函数2.localtime函数3.mktime函数 二、更加复杂的函数&#xff1a;gmtime函数,asctime函数,ctime函数4.gmtime函数5.asctime函数6.ctime函数 三、应用型&#xff1a;sleep函数&…

【以音频软件FFmpeg为例】通过Python脚本将软件路径添加到Windows系统环境变量中的实现与原理分析

在Windows系统中&#xff0c;你可以通过修改环境变量 PATH 来使得 ffmpeg.exe 可在任意路径下直接使用。要通过Python修改环境变量并立即生效&#xff0c;如图&#xff1a; 你可以使用以下代码&#xff1a; import os import winreg as reg# ffmpeg.exe的路径 ffmpeg_path …

计算机网络三张表(ARP表、MAC表、路由表)总结

参考&#xff1a; 网络三张表&#xff1a;ARP表, MAC表, 路由表&#xff0c;实现你的网络自由&#xff01;&#xff01;_mac表、arp表、路由表-CSDN博客 网络中的三张表&#xff1a;ARP表、MAC表、路由表 首先要明确一件事&#xff0c;如果一个主机要发送数据&#xff0c;那么必…

C++11 可变参数模版

目录 1.可变参数模版 1.1概念 1.2递归方式展开参数包 1.3逗号表达式展开参数包 1.可变参数模版 1.1概念 C11的新特性可变参数模板&#xff0c;这是一种允许模板函数或模板类接受任意数量参数的特性。可变参数模板极大地增强了模板的灵活性和表达能力&#xff0c;使得编写…

React和Vue有什么区别,如何选择?

React和Vue有什么区别&#xff0c;如何选择&#xff1f; React 和 Vue 是当前最受欢迎的前端框架之一&#xff0c;两者在开发者中都有极高的声誉。它们都旨在帮助开发人员构建用户界面&#xff0c;但在实现方式和适用场景上有所不同。如果你正考虑在项目中选择 React 或 Vue&a…