CSP-J 初赛(以满分为目标):第十六课 《STL容器与常见数据结构——C++自带的“数据结构工具箱”》


第十六课 STL容器与常见数据结构

------C++自带的"数据结构工具箱"

这一课主要复习:

复制代码
vector
stack
queue
priority_queue
set
map

并且把它们与:

复制代码
数组
栈
队列
堆
集合
映射

联系起来。


一、先问同学们一个问题

我们有一盒彩色积木。

如果要求:

把所有积木放进去。

可以用一个普通箱子。

如果要求:

最后放进去的积木先拿出来。

普通箱子就不太方便。

如果要求:

先来的积木先拿出来。

又需要另外一种箱子。

如果要求:

每次都把"最重要"的积木先拿出来。

又需要另一种箱子。

所以:

不同的问题,需要不同的数据结构。

这就是数据结构最核心的思想。


二、什么是数据结构?

给出的定义是:

数据结构是计算机存储、组织数据的方式。

特别强调:

精心选择的数据结构可以带来更高的运行或者存储效率。

小学生可以这样来理解:

数据结构就是"怎样把一堆数据装起来、管理起来"。

例如:

复制代码
数组      → 一排座位
stack     → 一摞盘子
queue     → 一列排队的人
priority_queue → 按优先级排列的队伍
set       → 不重复的集合
map       → 电话簿

三、STL是什么?

STL是:

Standard Template Library

中文一般叫:

C++标准模板库

它里面已经准备好了很多非常好用的:

复制代码
容器
算法
迭代器

所以我们不用每次都自己造轮子。

例如过去我们学数组:

复制代码
int a[100];

如果想要一个可以自动变长的数组,现在就可以使用:

复制代码
vector<int> a;

四、先建立一张"STL地图"

复制代码
                STL容器
                   │
       ┌───────────┼────────────┐
       │           │            │
       ↓           ↓            ↓
    vector       stack        queue
    动态数组      栈            队列
       │                         │
       │                         ↓
       │                    先进先出
       ↓
    priority_queue
       优先队列
       
       ┌───────────────┐
       ↓               ↓
      set             map
     集合             映射

接下来逐个认识。


五、第一位成员:vector

------会自动长大的数组

以前:

复制代码
int a[100];

最大只能放100个整数。

如果我们不知道到底需要多少个呢?

这时候:

复制代码
vector<int> a;

就非常方便。

可以把它理解成:

一个会自动扩容的数组。


六、vector最简单的使用

复制代码
#include <bits/stdc++.h>
using namespace std;

int main()
{
    vector<int> a;

    a.push_back(10);
    a.push_back(20);
    a.push_back(30);

    cout << a[0] << endl;
    cout << a[1] << endl;
    cout << a[2] << endl;
}

最后:

复制代码
10
20
30

七、push_back()是什么意思?

名字其实很好理解:

复制代码
push
+
back

就是:

从后面放进去。

例如:

复制代码
a.push_back(10);

变成:

复制代码
10

再:

复制代码
a.push_back(20);

变成:

复制代码
10 20

再:

复制代码
a.push_back(30);

变成:

复制代码
10 20 30

八、vector和数组有什么相同?

复制代码
vector<int> a;

和:

复制代码
int a[100];

都可以使用:

复制代码
a[i]

例如:

复制代码
a[0]
a[1]
a[2]

我们可以先把:

vector理解成"升级版数组"。


九、vector有什么不同?

普通数组:

复制代码
int a[100];

空间一开始就确定了。

而:

复制代码
vector<int> a;

可以随着:

复制代码
push_back()

不断增加元素。

例如:

复制代码
开始:
[]

push 10:
[10]

push 20:
[10,20]

push 30:
[10,20,30]

所以:

vector = 可以自动变长的数组


十、size()

想知道vector里有多少个元素:

复制代码
a.size()

例如:

复制代码
vector<int> a;

a.push_back(10);
a.push_back(20);
a.push_back(30);

cout << a.size();

结果:

复制代码
3

十一、vector遍历

最简单:

复制代码
for(int i=0;i<a.size();i++)
{
    cout << a[i] << " ";
}

这和数组的遍历:

复制代码
for(int i=0;i<n;i++)
{
    cout << a[i];
}

几乎一模一样。

所以:

学会数组以后,vector非常容易。


十二、vector还能和sort一起使用

这是CSP-J特别重要的组合。

复制代码
vector<int> a;

a.push_back(5);
a.push_back(2);
a.push_back(8);
a.push_back(1);

sort(a.begin(),a.end());

结果:

复制代码
1 2 5 8

所以:

复制代码
vector
+
sort

是非常常见的组合。


十三、这里第一次出现:begin()end()

复制代码
sort(a.begin(), a.end());

我们不用把它想得太复杂。

可以理解成:

复制代码
a.begin()
 ↓
第一个元素的位置

a.end()
 ↓
最后一个元素"后面"的位置

所以:

复制代码
sort(a.begin(),a.end());

意思就是:

把整个vector排序。

这一点与:

复制代码
sort(a, a+n);

非常类似。


十四、vector的几个常见操作

首先就是:

复制代码
a.push_back(x);

后面加入 x

复制代码
a.pop_back();

删除最后一个

复制代码
a.size();

元素个数

复制代码
a.empty();

判断是否为空

复制代码
a[i]

访问第 i 个元素


十五、第二位成员:stack

------一摞盘子

栈的定义非常明确:

栈是后进先出 LIFO(Last In First Out)的结构。

这是什么意思?

想象桌子上有一摞盘子:

复制代码
   ┌─────┐
   │  3  │ ← 最后放
   ├─────┤
   │  2  │
   ├─────┤
   │  1  │ ← 最先放
   └─────┘

你不能从中间拿。

只能:

从最上面拿。

所以:

后进先出


十六、C++中的stack

复制代码
stack<int> s;

放入:

复制代码
s.push(10);
s.push(20);
s.push(30);

现在:

复制代码
栈顶
 ↓
30
20
10

十七、top()

想看看最上面的元素:

复制代码
s.top()

结果:

复制代码
30

注意:

复制代码
s.top();

只是:

看看栈顶。

不会删除。


十八、pop()

复制代码
s.pop();

表示:

删除栈顶。

所以:

复制代码
s.push(10);
s.push(20);
s.push(30);

s.pop();

变成:

复制代码
20
10

十九、stack最重要的三个操作

复制代码
push
 ↓
入栈

top
 ↓
看栈顶

pop
 ↓
出栈

记忆口诀:

push放进去,top看最上,pop拿出来。


二十、注意一个非常容易错的地方

很多初学者以为:

复制代码
s.pop()

会返回被删除的数字。

实际上:

复制代码
s.pop();

不返回元素。

正确做法:

复制代码
int x = s.top();
s.pop();

先看:

复制代码
x = 栈顶

再删除:

复制代码
pop

二十一、如何判断stack是否为空?

复制代码
s.empty()

如果:

复制代码
true

说明:

空。

如果:

复制代码
false

说明:

不空。

因此:

复制代码
while(!s.empty())
{
    cout << s.top() << " ";
    s.pop();
}

就是:

不断把栈顶元素拿出来,直到栈为空。


二十二、这和CSP-J初赛题直接联系起来

考试中有这样的题:

元素依次入栈,判断哪些出栈序列不可能出现。

以及:

给定一串元素依次进入栈,问栈容量至少是多少。

这些题本质上都只考一个核心:

栈顶永远是最后进入、还没有出去的元素。


二十三、第三位成员:queue

------排队买奶茶

假设:

复制代码
小明
小红
小刚

依次来到奶茶店:

复制代码
小明 → 小红 → 小刚

谁先买?

当然:

小明。

这就是:

先进先出 FIFO

讲义也明确指出,队列是先进先出的线性表。


二十四、C++中的queue

复制代码
queue<int> q;

加入:

复制代码
q.push(10);
q.push(20);
q.push(30);

现在:

复制代码
队头         队尾
 ↓            ↓
10 → 20 → 30

二十五、front()

看最前面的元素:

复制代码
q.front()

结果:

复制代码
10

二十六、back()

看最后面的元素:

复制代码
q.back()

结果:

复制代码
30

二十七、pop()

复制代码
q.pop();

删除队头:

复制代码
10

被删除。

剩下:

复制代码
20 → 30

二十八、queue的核心操作

复制代码
push
 ↓
从队尾加入

front
 ↓
看队头

back
 ↓
看队尾

pop
 ↓
删除队头

口诀:

队尾进,队头出。


二十九、stack和queue比较

数据结构 特点
stack 后进先出 一端 同一端
queue 先进先出 队尾 队头

可以用两个生活例子记忆:

复制代码
stack
 ↓
一摞盘子

queue
 ↓
排队买票

三十、考试中的一个重要考点

考题中经常考到:

广度优先搜索(BFS)需要使用队列。

为什么?

因为BFS的思想是:

复制代码
先发现的人
 ↓
先处理

这正好是:

复制代码
先进先出

所以:

BFS → queue

以后看到:

复制代码
广度优先搜索
层序遍历
一层一层处理

要想到:

队列。


三十一、第四位成员:priority_queue

------VIP排行榜

现在问题来了。

普通队列:

复制代码
A → B → C → D

谁先处理?

A。

但是医院急诊室不是这样。

可能:

复制代码
普通病人
普通病人
紧急病人
普通病人

谁应该先处理?

紧急病人。

所以:

我们需要优先队列。


三十二、priority_queue是什么?

复制代码
priority_queue<int> q;

可以理解成:

一个永远把"最大值"放在最前面的队列。

例如:

复制代码
q.push(3);
q.push(10);
q.push(5);
q.push(7);

里面有:

复制代码
3 10 5 7

但:

复制代码
q.top()

得到:

复制代码
10

三十三、priority_queue最重要的三个操作

复制代码
q.push(x);

加入元素。

复制代码
q.top();

查看最高优先级元素。

复制代码
q.pop();

删除最高优先级元素。


三十四、默认priority_queue是谁优先?

默认:

最大值优先。

例如:

复制代码
priority_queue<int> q;

q.push(3);
q.push(8);
q.push(5);
q.push(1);

不断:

复制代码
cout << q.top() << " ";
q.pop();

得到:

复制代码
8 5 3 1

所以:

复制代码
priority_queue<int>
=
大根堆
=
最大值优先

三十五、如果想让最小值优先呢?

可以写:

复制代码
priority_queue<int, vector<int>, greater<int>> q;

这句话第一次看到可能非常吓人。

其实先记:

复制代码
默认
↓
最大值优先

greater<int>
↓
最小值优先

例如:

复制代码
priority_queue<int, vector<int>, greater<int>> q;

q.push(3);
q.push(8);
q.push(5);
q.push(1);

不断取:

复制代码
1 3 5 8

三十六、为什么叫"优先队列"?

因为普通queue:

复制代码
谁先来谁先走

而priority_queue:

复制代码
谁优先级最高谁先走

所以:

复制代码
queue
 ↓
时间顺序

priority_queue
 ↓
优先级顺序

这个区别必须掌握。


三十七、priority_queue和sort有什么区别?

例如:

复制代码
3 8 5 1

sort

把所有元素一次性排好。

priority_queue

不断加入元素,然后每次快速找到当前最优的那个。

所以可以理解成:

复制代码
sort
 ↓
先全部收集
 ↓
一次排序

priority_queue
 ↓
不断加入
 ↓
不断取当前最优

这在算法题中非常重要。


三十八、第五位成员:set

------一个不允许重复的集合

假设:

复制代码
1 2 3 3 3 4 5 5

如果老师说:

我只想知道有哪些不同的数字。

答案:

复制代码
1 2 3 4 5

这就是集合。

C++:

复制代码
set<int> s;

三十九、set最大的特点

自动去重

例如:

复制代码
set<int> s;

s.insert(3);
s.insert(5);
s.insert(3);
s.insert(8);
s.insert(5);

最终集合中:

复制代码
3 5 8

重复的:

复制代码
3
5

不会出现第二次。


四十、set还有一个重要特点:自动有序

普通:

复制代码
vector<int>

加入:

复制代码
5 2 8 3

可能就是:

复制代码
5 2 8 3

而:

复制代码
set<int>

插入:

复制代码
5
2
8
3

遍历时会按照顺序:

复制代码
2 3 5 8

所以:

set = 自动去重 + 自动排序

这是非常重要的认识。


四十一、set的常用操作

加入:

复制代码
s.insert(x);

删除:

复制代码
s.erase(x);

判断是否为空:

复制代码
s.empty();

元素个数:

复制代码
s.size();

查找:

复制代码
s.find(x);

四十二、setvector怎么选?

例如我要保存:

复制代码
3 3 2 5 2 8

如果使用:

复制代码
vector<int>

得到:

复制代码
3 3 2 5 2 8

如果使用:

复制代码
set<int>

得到:

复制代码
2 3 5 8

所以:

复制代码
vector
 ↓
允许重复
 ↓
保留插入顺序

set
 ↓
不允许重复
 ↓
自动有序

四十三、第六位成员:map

------超级电话簿

这是经常用到的一个数据结构。

就像电话簿:

复制代码
小明 → 138xxxx
小红 → 139xxxx
小刚 → 137xxxx

这里:

复制代码
姓名
 ↓
电话号码

就是:

key → value

C++:

复制代码
map<string,string> phone;

四十四、map最核心的思想

例如:

复制代码
map<string,int> score;

我们可以写:

复制代码
score["Tom"] = 95;
score["Jack"] = 88;
score["Lucy"] = 100;

于是:

复制代码
Tom  → 95
Jack → 88
Lucy → 100

这就是:

用一个"名字"找到一个"值"。


四十五、map的两个部分

每一个元素都可以看成:

复制代码
key → value

例如:

复制代码
apple → 5
banana → 8
orange → 3

这里:

复制代码
apple
banana
orange

是:

key

而:

复制代码
5
8
3

是:

value


四十六、map最常见的用途:统计次数

这是CSP-J特别重要的用途。

例如:

复制代码
1 2 1 3 2 1

统计每个数字出现次数。

复制代码
map<int,int> cnt;

cnt[1]++;
cnt[2]++;
cnt[1]++;
cnt[3]++;
cnt[2]++;
cnt[1]++;

最后:

复制代码
1 → 3
2 → 2
3 → 1

所以:

map是非常好用的"计数器"。


四十七、为什么cnt[x]++这么神奇?

例如第一次:

复制代码
cnt[5]++;

如果5还不存在:

复制代码
cnt[5]

会得到默认的0。

然后:

复制代码
0 + 1 = 1

第二次:

复制代码
cnt[5]++;

变成:

复制代码
2

第三次:

复制代码
3

所以:

复制代码
cnt[x]++;

就是:

把x出现次数加1。


四十八、map和数组统计有什么关系?

以前统计:

复制代码
1~100

可以:

复制代码
int cnt[101] = {};

然后:

复制代码
cnt[x]++;

但是如果数字可能是:

复制代码
1000000000

或者:

复制代码
-99999999

用一个巨大数组就不方便。

这时候:

复制代码
map<int,int> cnt;

就非常方便。

所以:

复制代码
数组计数
 ↓
数据范围小

map计数
 ↓
数据范围可以很大

四十九、unordered_map是什么?

我们不需要深入实现哈希表。

但程序阅读中会看到:

复制代码
unordered_map<int,int> cnt;

可以先理解:

它也是"key → value"的电话簿。

区别简单记:

复制代码
map
 ↓
有序

unordered_map
 ↓
通常不保证有序

所以:

复制代码
map
=
有序电话簿

unordered_map
=
不按顺序排列的快速电话簿

五十、建立一张STL容器对比表

STL容器 生活中的东西 核心特点
vector 自动变长的盒子 动态数组
stack 一摞盘子 后进先出
queue 排队 先进先出
priority_queue VIP排行榜 优先级最高先出
set 不重复的集合 去重、有序
map 电话簿 key → value

五十一、STL操作口诀

vector

复制代码
push_back
pop_back
size
empty

stack

复制代码
push
top
pop
empty

queue

复制代码
push
front
back
pop
empty

priority_queue

复制代码
push
top
pop
empty

set

复制代码
insert
erase
find
size
empty

map

复制代码
[key]
insert
erase
find
size
empty

五十二、考试中重要的比较:stackqueuepriority_queue

这三个特别容易混淆。

stack

复制代码
1进
2进
3进

3出
2出
1出

即:

后进先出。


queue

复制代码
1进
2进
3进

1出
2出
3出

即:

先进先出。


priority_queue

复制代码
3进
10进
5进
7进

先出:

复制代码
10

然后:

复制代码
7

然后:

复制代码
5

最后:

复制代码
3

即:

谁优先级高谁先出。


五十三、程序阅读题

复制代码
vector<int> a;

a.push_back(5);
a.push_back(2);
a.push_back(8);
a.push_back(2);

sort(a.begin(),a.end());

cout << a[1];

先:

复制代码
5 2 8 2

排序:

复制代码
2 2 5 8

所以:

复制代码
a[1] = 2

答案:

复制代码
2

五十四、再看stack

复制代码
stack<int> s;

s.push(1);
s.push(2);
s.push(3);

cout << s.top() << " ";

s.pop();

cout << s.top();

过程:

复制代码
push 1
→ 1

push 2
→ 1 2

push 3
→ 1 2 3

第一次:

复制代码
s.top()

得到:

复制代码
3

然后:

复制代码
s.pop()

删除3。

现在:

复制代码
1 2

再次:

复制代码
s.top()

得到:

复制代码
2

所以:

复制代码
3 2

五十五、再看queue

复制代码
queue<int> q;

q.push(1);
q.push(2);
q.push(3);

cout << q.front() << " ";

q.pop();

cout << q.front();

过程:

复制代码
1 → 2 → 3

第一次:

复制代码
front = 1

然后:

复制代码
pop

删除1。

剩下:

复制代码
2 → 3

所以第二次:

复制代码
front = 2

答案:

复制代码
1 2

五十六、再看priority_queue

复制代码
priority_queue<int> q;

q.push(3);
q.push(8);
q.push(5);

cout << q.top() << " ";

q.pop();

cout << q.top();

最大值优先:

复制代码
8

删除8。

剩下:

复制代码
5
3

所以:

复制代码
5

答案:

复制代码
8 5

五十七、再看set

复制代码
set<int> s;

s.insert(5);
s.insert(2);
s.insert(5);
s.insert(3);

for(auto x:s)
    cout << x << " ";

插入:

复制代码
5
2
5
3

重复的5只保留一次。

最终:

复制代码
2 3 5

所以输出:

复制代码
2 3 5

五十八、再看map

复制代码
map<string,int> m;

m["Tom"] = 90;
m["Jack"] = 80;
m["Tom"]++;

cout << m["Tom"];

第一次:

复制代码
Tom → 90

然后:

复制代码
m["Tom"]++;

变成:

复制代码
Tom → 91

所以输出:

复制代码
91

五十九、STL程序阅读"四步法"

以后我们看到一个STL容器,不要慌。

第一步:

认容器

看到:

复制代码
vector
stack
queue
priority_queue
set
map

马上知道它是什么。


第二步:

认规则

例如:

复制代码
stack
→ 后进先出

queue
→ 先进先出

priority_queue
→ 优先级最高先出

set
→ 去重+有序

map
→ key找value

第三步:

画状态

例如:

复制代码
q.push(3);
q.push(5);
q.pop();

不要只在脑子里想。

画:

复制代码
3
 ↓
3 5
 ↓
5

第四步:

最后看输出

不要一看到:

复制代码
cout

就急着算。

先把容器状态模拟完。


六十、CSP-J容易考的对应关系

这部分非常重要。

看到:

复制代码
"后进先出"

想到:

stack

看到:

复制代码
"先进先出"

想到:

queue

看到:

复制代码
"广度优先搜索"

想到:

queue

看到:

复制代码
"每次取最大"

想到:

priority_queue<int>

看到:

复制代码
"每次取最小"

想到:

小根堆 / 最小优先的 priority_queue

看到:

复制代码
"去掉重复元素"

想到:

set

看到:

复制代码
"某个东西对应一个值"

想到:

map

看到:

复制代码
"动态数组"

想到:

vector


六十一、一个重要的"选择数据结构"训练

给同学们几个场景,来看适合哪种数据结构:

场景1

班级里有很多数字,需要动态增加。

答案:

复制代码
vector

场景2

浏览器的后退操作,最近访问的页面最先回来。

答案:

复制代码
stack

场景3

食堂排队,先来的人先打饭。

答案:

复制代码
queue

场景4

每次从一堆任务中选择优先级最高的任务。

答案:

复制代码
priority_queue

场景5

给一堆数字去重。

答案:

复制代码
set

场景6

统计每个单词出现了多少次。

答案:

复制代码
map

六十二、把本课和前面学过的知识串起来

本课不是一个孤立的新章节。

前面我们已经学了:

复制代码
数组
 ↓
结构体
 ↓
排序

现在可以:

复制代码
vector
 ↓
可以装结构体

sort
 ↓
可以给vector排序

priority_queue
 ↓
可以装结构体

set
 ↓
可以保存结构体

map
 ↓
可以统计数据

例如:

复制代码
vector<Student> a;

就是:

动态的结构体数组。

再:

复制代码
sort(a.begin(),a.end(),cmp);

就是:

给动态结构体数组排序。

这与前面的课连接起来了。


六十三、vector里也可以放结构体

例如:

复制代码
struct Student
{
    string name;
    int score;
};

vector<Student> a;

然后:

复制代码
a.push_back({"Tom",95});
a.push_back({"Jack",90});

这时候:

复制代码
a
 ↓
┌───────────────┐
│ Tom   95      │
├───────────────┤
│ Jack  90      │
└───────────────┘

再:

复制代码
sort(a.begin(),a.end(),cmp);

这就是:

结构体动态数组的排序


六十四、本课还有一个重要的思想

同学们以前可能认为:

数据结构就是"数组、链表、栈、队列"。

现在要慢慢建立一个更深刻的认识:

数据结构不是为了"记名字",而是为了"选择合适的操作方式"。

例如:

复制代码
我需要随机访问
 ↓
vector

我只需要最后进来的先出来
 ↓
stack

我需要先进先出
 ↓
queue

我需要每次拿最大/最小
 ↓
priority_queue

我需要去重
 ↓
set

我需要 key → value
 ↓
map

这才是学习数据结构真正的目的。


六十五、本课知识地图

复制代码
                       STL
                        │
       ┌────────────────┼────────────────┐
       │                │                │
       ↓                ↓                ↓
    vector            stack             queue
   动态数组             栈                队列
       │                │                │
       ↓                ↓                ↓
   随机访问           后进先出           先进先出
       
                       │
                       ↓
                priority_queue
                    优先队列
                       │
                       ↓
                 最大/最小优先


       ┌────────────────────────┐
       │                        │
       ↓                        ↓
      set                      map
      集合                     映射
       │                        │
       ↓                        ↓
   去重+有序                key → value
                              │
                              ↓
                            计数

六十六、本课CSP-J必背清单

1、vector

复制代码
vector<int> a;
a.push_back(x);
a.pop_back();
a.size();
a[i];

动态数组。


2、stack

复制代码
stack<int> s;
s.push(x);
s.top();
s.pop();

后进先出。


3、queue

复制代码
queue<int> q;
q.push(x);
q.front();
q.back();
q.pop();

先进先出。


4、priority_queue

复制代码
priority_queue<int> q;
q.push(x);
q.top();
q.pop();

默认最大值优先。


5、set

复制代码
set<int> s;
s.insert(x);
s.erase(x);
s.find(x);

自动去重、自动有序。


6、map

复制代码
map<int,int> mp;
mp[x]++;

key → value,非常适合计数。


六十七、一句话口诀

vector是动态数组,数据增加不用愁。

stack像一摞盘子,后进先出记心头。

queue就是排队,先进先出往前走。

priority_queue看优先级,默认最大值先出头。

set自动去重还排序。

map像一本电话簿,key找到value。

看到BFS想队列,看到去重想集合。

看到统计想map,看到最大最小想优先队列。


六十八、课堂训练

第1部分:vector + stack

复制代码
vector
 ↓
动态数组
 ↓
push_back
 ↓
遍历
 ↓
sort

stack
 ↓
LIFO
 ↓
push/top/pop
 ↓
栈模拟题

重点:

数组升级 + 栈模拟


第2部分:queue + priority_queue

复制代码
queue
 ↓
FIFO
 ↓
front/back/pop
 ↓
BFS为什么需要队列

priority_queue
 ↓
优先级
 ↓
大根堆
 ↓
小根堆

重点:

看到"先进先出"马上想到queue;看到"每次取最大/最小"马上想到priority_queue。


第3部分:set + map + 综合阅读

复制代码
set
 ↓
去重
 ↓
有序

map
 ↓
key/value
 ↓
计数

最后综合:
vector + sort
map + 统计
set + 去重
priority_queue + 取最值

相关推荐
luj_176834 分钟前
断舍离中的项目管理智慧
c语言·开发语言·c++·经验分享·算法
FFZero135 分钟前
[mpv架构] (三) mpv 怎么实现 MP4 秒开?
c++·音视频·mpv
OPEN-F1 小时前
C++进阶教程:文件流与字符串流
开发语言·c++·算法
Android打工人1 小时前
c++ 、java 融为一体2,c++ 实例化Android虚拟机直接运行java,c,java 一个进程号
android·java·c++
jimy11 小时前
std::move(a)本质是把a转换成右值引用类型
开发语言·c++
01_ice1 小时前
c++类和对象(中)
c++·算法
码匠许师傅1 小时前
【设计模式精讲】4.单例模式(Singleton)
c++·单例模式·设计模式
wind100322 小时前
VC++ 运行库 vcredist 安装失败|CLR 80131522 报错完整修复
开发语言·c++·游戏
OPEN-F8 小时前
C++进阶教程:继承与多态
开发语言·c++