跳到主要内容C++ 语法基础:STL、位运算与常用库函数 | 极客日志C++算法
C++ 语法基础:STL、位运算与常用库函数
本文介绍了 C++ 标准模板库(STL)的基础知识,涵盖 vector、queue、stack、deque、set 和 map 容器的常用操作及迭代器使用。同时讲解了位运算的基本符号与常见技巧,如 lowbit 和获取指定位数字。最后总结了 algorithm 库中的常用函数,包括 reverse、unique、random_shuffle、sort 以及 lower_bound/upper_bound 的用法与示例代码。
KernelLab0 浏览 STL
Vector
Vector 是一种序列容器,允许在运行时动态地插入和删除元素。使用时需要包含 <vector> 头文件。
size 返回 vector 的实际长度,empty 函数返回一个 bool 类型,表明 vector 是否为空。
- 二者的时间复杂度都是 O(1)。所有的 STL 容器都支持这两个方法。
- 迭代器就像 STL 容器的指针,可以用
* 操作符解除引用。
- Vector 的迭代器是'随机访问迭代器',可以把 vector 的迭代器与一个整数相加减,其行为和指针的移动类似。可以把 vector 的两个迭代器相减,其结果也和指针相减类似,得到两个迭代器对应下标之间的距离。
begin() 函数返回指向 vector 中的第一个元素的迭代器。end() 函数返回 vector 的尾部,就是最后一个元素的下一个。front() 表示返回 vector 的第一个元素。back() 表示返回 vector 的最后一个元素。push_back(x) 表示在 vector 的末尾插入元素 x。pop_back() 表示删除 vector 的末尾元素。Vector 实例
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> a;
a.push_back(1);
a.push_back(2);
a.push_back(3);
a.push_back(4);
a.push_back(5);
int len = a.size();
bool is_empty = a.empty();
cout << len << " " << is_empty << endl;
int first = a.front();
int last = a.back();
cout << first << " " << last << endl;
a.pop_back();
a.erase(a.begin() + 2);
first = a.front();
last = a.back();
cout << first << " " << last << endl;
for (vector<int>::iterator it = a.begin(); it != a.end(); it++) {
cout << *it << endl;
}
cout << a[2] << endl;
a.clear();
len = a.size();
is_empty = a.empty();
cout << len << " " << is_empty << endl;
return 0;
}
Vector 声明
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> a;
vector<int> b[233];
return 0;
}
Queue
使用时需要包含 <queue> 头文件。Queue 主要包括循环队列 queue 和优先队列 priority_queue 两个容器。遵循元素在队首添加,队尾移出的规则。
优先队列 Priority_Queue
实例
#include <iostream>
#include <queue>
using namespace std;
int main() {
priority_queue<int> q;
q.push(1);
q.push(2);
q.push(3);
q.push(4);
q.push(5);
priority_queue<int> m = q;
while (!m.empty()) {
cout << m.top() << endl;
m.pop();
}
q.pop();
q.pop();
while (!q.empty()) {
cout << q.top() << endl;
q.pop();
}
return 0;
}
常用函数
top 函数:返回队列顶部的元素(并不删除)。
pop 函数:移除队列顶部的元素。
push 函数:向队列中添加一个元素。
循环队列 Queue
实例
#include <iostream>
#include <queue>
using namespace std;
int main() {
queue<int> q;
q.push(1);
q.push(2);
q.push(3);
q.push(4);
queue<int> m = q;
while (!m.empty()) {
cout << m.front() << endl;
m.pop();
}
cout << q.front() << endl;
cout << q.back() << endl;
cout << q.size() << endl;
return 0;
}
常用函数
back 函数:返回队尾元素。
front 函数:返回队首元素。
pop 函数:移除队首元素。
push 函数:在队尾添加一个元素。
声明
#include <iostream>
#include <queue>
using namespace std;
int main() {
queue<int> q;
priority_queue<int> a;
priority_queue<int, vector<int>, greater<int>> b;
priority_queue<pair<int, int>> c;
return 0;
}
Stack
实例
#include <iostream>
#include <stack>
using namespace std;
int main() {
stack<int> s;
s.push(1);
s.push(2);
s.push(3);
s.push(4);
stack<int> t = s;
while (!t.empty()) {
cout << t.top() << endl;
t.pop();
}
s.pop();
s.pop();
while (!s.empty()) {
cout << s.top() << endl;
s.pop();
}
return 0;
}
常用函数
top 函数:返回栈顶元素,但不删除。
pop 函数:移除栈顶元素。
push 函数:在栈顶添加一个元素。
Deque
实例
#include <iostream>
#include <deque>
using namespace std;
int main() {
deque<int> q;
q.push_front(1);
q.push_back(2);
q.push_front(3);
q.push_back(4);
int len = q.size();
bool is_empty = q.empty();
cout << len << " " << is_empty << endl;
for (deque<int>::iterator it = q.begin(); it != q.end(); it++) {
cout << *it << endl;
}
q.pop_back();
q.pop_front();
len = q.size();
is_empty = q.empty();
cout << len << " " << is_empty << endl;
for (deque<int>::iterator it = q.begin(); it != q.end(); it++) {
cout << *it << endl;
}
q.clear();
len = q.size();
is_empty = q.empty();
cout << len << " " << is_empty << endl;
return 0;
}
常用函数
clear 函数:清空队列。
pop_front 和 pop_back 函数:从队头出队,从队尾出队。
push_front 和 push_back 函数:从队头入队,从队尾入队。
front 和 back 函数:返回队头和队尾元素。
begin 和 end 函数:返回 deque 的头为迭代器。
声明
#include <iostream>
#include <deque>
using namespace std;
int main() {
deque<int> q;
return 0;
}
Set
size() 用来获取容器的长度。
empty() 用来判断容器是否非空。
clear() 用来清空容器元素。
- Set 和 multiset 的迭代器称为'双向访问迭代器',不支持'随机访问',支持星号
* 解除引用,仅支持 ++ 和 -- 两个与算术相关的操作。
- 设
it 是一个迭代器,例如 set<int>::iterator it;。
- 若把
it++,则 it 会指向'下一个'元素。这里的'下一个'元素是指在元素从小到大排序的结果中,排在 it 下一名的元素。同理,若把 it--,则 it 将会指向排在'上一个'的元素。
- 返回首、尾迭代器,时间复杂度均为 O(1)。
s.begin() 是指向集合中最小元素的迭代器。
s.end() 是指向集合中最大元素的下一个位置的迭代器。
s.insert(x) 把一个元素 x 插入到集合 s 中,时间复杂度为 O(logn)。
- 在 set 中,若元素已存在,则不会重复插入该元素,对集合的状态无影响。
- 这两个函数的用法与 find 类似,但查找的条件略有不同,时间复杂度为 O(logn)。
s.lower_bound(x) 查找大于等于 x 的元素中最小的一个,并返回指向该元素的迭代器。
s.upper_bound(x) 查找大于 x 的元素中最小的一个,并返回指向该元素的迭代器。
- 设
it 是一个迭代器,s.erase(it) 从 s 中删除迭代器 it 指向的元素,时间复杂度为 O(logn)。
- 设 x 是一个元素,
s.erase(x) 从 s 中删除所有等于 x 的元素,时间复杂度为 O(k+logn),其中 k 是被删除的元素个数。
实例
#include <iostream>
#include <set>
using namespace std;
int main() {
set<int> s;
s.insert(1);
s.insert(2);
s.insert(3);
s.insert(4);
s.insert(5);
int len = s.size();
bool is_empty = s.empty();
cout << len << " " << is_empty << endl;
for (set<int>::iterator it = s.begin(); it != s.end(); it++) {
cout << *it << endl;
}
s.erase(3);
len = s.size();
is_empty = s.empty();
cout << len << " " << is_empty << endl;
for (set<int>::iterator it = s.begin(); it != s.end(); it++) {
cout << *it << endl;
}
if (s.find(2) != s.end()) {
cout << "2 is yes" << endl;
} else {
cout << "2 is no" << endl;
}
int count = s.count(0);
cout << count << endl;
return 0;
}
常用函数
count 函数:返回集合 s 中等于 x 的元素个数,时间复杂度为 O(k+logn),其中 k 为元素 x 的个数。
erase 函数:删除元素。
lower_bound 和 upper_bound 函数:二分查找边界。
find 函数:在集合 s 中查找等于 x 的元素,并返回指向该元素的迭代器。若不存在,则返回 s.end()。时间复杂度为 O(logn)。
insert 函数:插入元素。
begin 和 end 函数:返回首尾迭代器。
size、empty、clear 函数:基本容器操作。
声明
#include <iostream>
#include <set>
using namespace std;
int main() {
set<int> s;
return 0;
}
Map
实例
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
map<string, int> employees;
employees.insert(make_pair("Alice", 30));
employees.insert(make_pair("Bob", 25));
employees.insert(make_pair("Charlie", 35));
for (map<string, int>::iterator it = employees.begin(); it != employees.end(); ++it) {
cout << it->first << ":" << it->second << endl;
}
int len = employees.size();
bool is_empty = employees.empty();
cout << len << " " << is_empty << endl;
map<string, int>::iterator it = employees.find("Bob");
if (it != employees.end()) {
if (it->second == 25) {
cout << "Bob: 25 is yes" << endl;
} else {
cout << "Bob: 25 is no" << endl;
}
} else {
cout << "Bob: 25 is no" << endl;
}
employees.clear();
len = employees.size();
is_empty = employees.empty();
cout << len << " " << is_empty << endl;
return 0;
}
常用函数
find 函数:在变量名为 h 的 map 中查找 key 为 x 的二元组。
insert 和 erase 函数:与 set 类似,但其参数均是 pair<key_type, value_type>。
size、empty、clear、begin、end 函数:和 set 类似。
声明
Map 容器是一个键值对 key-value 的映射,其内部实现是一棵以 key 为关键码的红黑树。Map 的 key 和 value 可以是任意类型,其中 key 必须定义小于号运算符。
#include <iostream>
#include <map>
using namespace std;
int main() {
map<long long, bool> vis;
return 0;
}
位运算
位运算符号
常见操作
Lowbit(x) = x & -x,返回 x 的最后一位 1
#include <iostream>
#include <string>
using namespace std;
int main() {
int num;
cin >> num;
int lowbit = num & -num;
cout << lowbit << endl;
return 0;
}
#include <iostream>
#include <string>
using namespace std;
int main() {
int num;
cin >> num;
int k;
cin >> k;
cout << ((num >> k) & 1) << endl;
return 0;
}
常用库函数
Reverse 函数
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main() {
int a[10] = {1, 2, 3, 4, 5, 6, 5, 4, 3, 2};
for (int i = 0; i < 10; i++) {
cout << a[i] << endl;
}
cout << endl;
reverse(a, a + 10);
for (int i = 0; i < 10; i++) {
cout << a[i] << endl;
}
cout << endl;
vector<int> q;
q.push_back(1);
q.push_back(2);
q.push_back(3);
q.push_back(4);
for (vector<int>::iterator it = q.begin(); it != q.end(); it++) {
cout << *it << endl;
}
cout << endl;
reverse(q.begin(), q.end());
for (vector<int>::iterator it = q.begin(); it != q.end(); it++) {
cout << *it << endl;
}
return 0;
}
Unique 函数
返回去重(只去掉相邻的相同元素)之后的尾迭代器(或指针),仍然为前闭后开,即这个迭代器是去重之后末尾元素的下一个位置。该函数常用于离散化,利用迭代器(或指针)的减法,可计算出去重后的元素个数。
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main() {
vector<int> q;
q.push_back(1);
q.push_back(2);
q.push_back(2);
q.push_back(2);
q.push_back(3);
q.push_back(3);
q.push_back(4);
for (vector<int>::iterator it = q.begin(); it != q.end(); it++) {
cout << *it << endl;
}
cout << endl;
vector<int>::iterator new_end = unique(q.begin(), q.end());
q.erase(new_end, q.end());
int m = q.size();
cout << "Number of unique elements: " << m << endl;
cout << "After removing duplicates: ";
for (vector<int>::iterator it = q.begin(); it != q.end(); it++) {
cout << *it << " ";
}
cout << endl;
return 0;
}
Random_Shuffle 函数
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main() {
vector<int> a;
a.push_back(1);
a.push_back(2);
a.push_back(3);
a.push_back(4);
a.push_back(5);
for (vector<int>::iterator it = a.begin(); it != a.end(); it++) {
cout << *it << endl;
}
cout << endl;
random_shuffle(a.begin(), a.end());
for (vector<int>::iterator it = a.begin(); it != a.end(); it++) {
cout << *it << endl;
}
return 0;
}
Sort 函数
对两个迭代器(或指针)指定的部分进行快速排序。默认是升序排列。
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int a[10] = {1, 2, 3, 2, 1, 4, 3, 2, 1, 10};
sort(a, a + 10);
for (int i = 0; i < 10; i++) {
cout << a[i] << endl;
}
cout << endl;
sort(a, a + 10, greater<int>());
for (int i = 0; i < 10; i++) {
cout << a[i] << endl;
}
return 0;
}
Lower_Bound/Upper_Bound 函数
lower_bound 的第三个参数传入一个元素 x,在两个迭代器(指针)指定的部分上执行二分查找,返回指向第一个大于等于 x 的元素的位置的迭代器(指针)。
upper_bound 的用法和 lower_bound 大致相同,唯一的区别是查找第一个大于 x 的元素。当然,两个迭代器(指针)指定的部分应该是提前排好序的。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int a[10] = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
sort(a, a + 10);
int i = lower_bound(a, a + 10, 5) - a;
cout << i << endl;
int j = upper_bound(a, a + 10, 5) - a;
cout << j << endl;
return 0;
}
微信扫一扫,关注极客日志
微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
- Markdown 转 HTML
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML 转 Markdown 互为补充。 在线工具,Markdown 转 HTML在线工具,online
- HTML 转 Markdown
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML 转 Markdown在线工具,online
- JSON 压缩
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online