C++常用STL及常用库函数

C++常用STL及常用库函数

参考自AcWing的 语法基础课

/**
 * vector
 * queue
 * stack
 * deque  双端队列
 * set
 * map
 * bitset
 * pair
 * 位运算
 * 常用库函数:
 * 		reverse、unique、random_shuffle、sort
 * 		lower_bound/upper_bound、nth_element
 */

vector

#include <iostream>
#include <vector>

using namespace std;

int main() {
    
    
    // 定义vector
    vector<int> a;  // 定义一个空vector
    vector<int> b(3);  // 定义一个长度为3,值全为0的vector
    vector<int> c({
    
    1, 2, 3});  // 定义一个包含元素1,2,3的vector
    vector<vector<int>> d(2, vector<int>(3));  // 定义一个2x3矩阵,值全为0
    struct Rec {
    
    
        int x, y;
    };
    vector<Rec> e;
    // 遍历vector
    for (int i = 0; i < c.size(); i++) cout << c[i] <<' ';
    cout << endl;
    for (vector<int>::iterator i = c.begin(); i < c.end(); i++) cout << *i << ' ';
    cout << endl;
    for (auto x : c) cout << x << ' ';
    cout << endl;
    // 获取vector第一个和最后一个元素
    cout << c.front() << ' ' << c[0] << ' ' << *c.begin() << endl;  // 第一个元素:c[0]常用
    cout << c.back() << ' ' << c[c.size() - 1] << endl;  // 最后一个元素:c.back()常用
    // 在vector尾部添加、删除元素
    c.push_back(4);
    c.pop_back();
    c.pop_back();
    cout << c.size() << endl;  // 2
    // 清空vector
    c.clear();
    cout << c.size() << endl;  // 0
    // vector比较运算
    vector<int> a1({
    
    1,2,3}), a2({
    
    1,2});
    cout << (a1 >= a2) << endl;  // 1
    
    return 0;
}

queue

#include <iostream>
#include <queue>

using namespace std;

int main() {
    
    
    // 定义 queue
    queue<int> q;
    // 入队、出队
    q.push(4);  // 4
    q.push(3);  // 4,3
    q.push(7);  // 4,3,7
    q.pop();  // 3,7
    // 获取 queue 队首和队尾元素
    cout << q.front() << endl;  // 返回队首元素: 3
    cout << q.back() << endl;  // 返回队尾元素: 7
    // 清空 queue:不存在clear(),直接重新定义即可
    q = queue<int>();
    cout << q.size() << endl;  // 0
    cout << q.empty() << endl;  // 1
    
    
    // 定义 priority_queue
    priority_queue<int> a;  // 大根堆
    priority_queue<int, vector<int>, greater<int>> b;  // 小根堆
    struct Rec {
    
    
        int a, b;
        bool operator< (const Rec &t) const {
    
    
            return a < t.a;
        }
    };
    priority_queue<Rec> c;  // 大根堆需要重载小于号,小根堆需要重载大于号
    // priority_queue 中插入元素,删除元素
    c.push({
    
    1, 2}); c.push({
    
    6, 7});
    c.push({
    
    5, 4}); c.push({
    
    3, 9});
    c.pop();
    // 返回堆顶元素
    auto t = c.top();
    cout << t.a << ' ' << t.b << endl;  // 5 4
    
    return 0;
}

stack

#include <iostream>
#include <stack>

using namespace std;

int main() {
    
    
    // 定义 stack
    stack<int> stk;
    // 入栈,出栈
    stk.push(20); stk.push(10); stk.push(30);
    stk.pop();  // 弹出30
    // 返回栈顶元素
    cout << stk.top() << endl;  // 10
    // 清空 stack:不存在clear(),直接重新定义即可
    stk = stack<int>();
    cout << stk.size() << endl;  // 0
    cout << stk.empty() << endl;  // 1
    
    return 0;
}

deque

#include <iostream>
#include <deque>

using namespace std;

int main() {
    
    
    // 定义 deque
    deque<int> d;
    // 双端队列中插入、删除元素
    d.push_back(20); d.push_back(10);  // 尾部插入数据: 20,10
    d.pop_back();  // 弹出一个尾部数据10: 20
    d.push_front(40); d.push_front(30);  // 头部插入数据: 30,40,20
    d.pop_front();  // 弹出一个头部数据30: 40,20
    // 遍历 deque
    for (int i = 0; i < d.size(); i++) cout << d[i] << ' ';
    cout << endl;
    for (deque<int>::iterator i = d.begin(); i < d.end(); i++) cout << *i << ' ';
    cout << endl;
    for (auto x : d) cout << x << ' ';
    cout << endl;
    // 返回头部和尾部元素
    cout << d.front() << endl;  // 40
    cout << d.back() << endl;  // 20
    // 清空 deque
    d.clear();
    cout << d.size() << endl;  // 0
    cout << d.empty() << endl;  // 1
    
    return 0;
}

set

#include <iostream>
#include <set>

using namespace std;

int main() {
    
    
    // 定义 set,元素不能重复,内部实现是红黑树,可以保持有序
    set<int> a;
    struct Rec {
    
    
        int x, y;
        bool operator< (const Rec &t) const {
    
    
            return x < t.x;
        }
    };
    set<Rec> b;
    // set 中插入、删除元素
    a.insert(20); a.insert(3); a.insert(1); a.insert(40);
    a.erase(3); 
    a.erase(a.find(40));  // 可以这样写,但没有必要,在multiset中有必要这样写
    // 返回最后一个元素 a: 1, 20
    cout << "最后一个元素:" << *a.rbegin() << endl;
    // 遍历 set
    for (int x : a) cout << x << ' ';
    cout << endl;
    for (set<int>::iterator it = a.begin(); it != a.end(); it++)  // 不能用 <
        cout << *it << ' ';
    cout << endl;
    // set 中寻找某元素,find返回第一个迭代器
    if (a.find(20) != a.end()) cout << "20在a中存在" << endl;
    else cout << "不存在" << endl;
    // lower_bound/upper_nound
    a.insert(4); a.insert(12);  // a: 1, 4, 12, 20
    cout << *a.lower_bound(4) << endl;  // 返回大于等于4的最小元素的迭代器: 4
    cout << *a.upper_bound(4) << endl;  // 返回大于4的最小元素的迭代器: 12
    // 清空 set
    a.clear();
    cout << a.size() << endl;  // 0
    cout << a.empty() << endl;  // 1
    
    
    cout << "==============================" << endl;
    // 定义 multiset
    multiset<int> s;  // 有序,元素可以重复的set
    // multiset 中插入、删除元素
    s.insert(3); s.insert(3); s.insert(3); s.insert(2); s.insert(1);
    s.erase(2);  // 如果存在多个2,会全部删掉
    s.erase(s.find(3));  // 删除第一个3
    // 统计某个元素出现的次数
    cout << s.count(3) << endl;  // 此时3出现2次
    // 其余同set, 省略
    
    return 0;
}
  • 另外unordered_set和set用法一致,但是unordered_set是基于哈希表实现的,内部是无序的,因此不存在lower_bound/upper_bound这两个函数
  • 另外unordered_multiset和multiset用法一致,但是unordered_multiset是基于哈希表实现的,内部是无序的,因此不存在lower_bound/upper_bound这两个函数

map

#include <iostream>
#include <map>

#define x first
#define y second

using namespace std;

int main() {
    
    
    // 定义 map,元素不能重复,内部实现是红黑树,可以保持有序
    map<string, int> a;
    
    // map 中插入、删除元素
    a.insert({
    
    "wxx", 21}); a["hh"] = 18; a["other"] = 20;
    a.erase("other");
    
    // 返回最后一个元素
    auto t = a.rbegin();
    cout << t->x << ": " << t->y << endl;
    
    // 遍历 map
    for (map<string, int>::iterator p = a.begin(); p != a.end(); p++)
        cout << "{" << p->x << ": " << p->y << "} ";
    cout << endl;
    for (auto p : a)
        cout << "{" << p.x << ": " << p.y << "} ";
    cout << endl;
    for (auto &[k, v] : a)
        cout << "{" << k << ": " << v << "} ";
    cout << endl;
    
    // map 中寻找某元素,find返回第一个迭代器
    if (a.find("wxx") != a.end()) cout << "wxx在a中存在" << endl;
    else cout << "不存在" << endl;
    
    // lower_bound/upper_nound
    a["c1"] = 2; a["c2"] = 4;  // a: {c1: 2} {c2: 4} {hh: 18} {wxx: 21}
    auto t1 = a.lower_bound("c1"), t2 = a.upper_bound("c1");
    // 返回大于等于"c1"的最小元素的迭代器: {c1: 2}
    cout << "{" << t1->x << ": " << t1->y << "} " << endl;
    // 返回大于"c1"的最小元素的迭代器: {c2: 4}
    cout << "{" << t2->x << ": " << t2->y << "} " << endl;
    
    // 清空 map
    a.clear();
    cout << a.size() << endl;  // 0
    cout << a.empty() << endl;  // 1
    
    
    // multimap使用很少,这里先不做介绍
    
    return 0;
}
  • 另外unordered_map和map用法一致,但是unordered_map是基于哈希表实现的,内部是无序的,因此不存在lower_bound/upper_bound这两个函数

bitset

#include <iostream>
#include <bitset>

using namespace std;

int main() {
    
    
    // 定义 bitset
    bitset<1000> a, b;
    // 赋值
    a[0] = 1; a[1] = 1; b[2] = 1; b[200] = 1;
    a.set(3);  // 等价于a[3] = 1
    a.reset(3);  // 等价于a[3] = 0
    // 位运算
    a &= b;
    a |= b;
    // 输出1的个数
    cout << a.count() << endl;
    
    return 0;
}

pair

#include <iostream>
#include <vector>

#define x first
#define y second

using namespace std;

typedef pair<int, int> PII;

int main() {
    
    
    // 定义 pair
    PII a = {
    
    1, 2}, b = {
    
    1, 3};
    PII c = make_pair(5, 8);  // c++99写法
    // pair支持双关键子比较
    cout << (a > b) << endl;  // 0
    // 输出pair
    cout << "(" << a.first << ", " << a.second << ")" << endl;
    
    return 0;
}

位运算

/*
    & 与
    | 或
    ~ 非
    ^ 异或
    >> 右移
    << 左移

    常用操作:
        (1)	求x的第k位数字  x >> k & 1
        (2)	lowbit(x) = x & -x,返回x的最后一位1
*/

常用库函数

reverse

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main() {
    
    
    
    // 翻转 vector
    vector<int> a({
    
    1, 2, 3, 4, 5});
    reverse(a.begin(), a.end());
    for (int x : a) cout << x << ' ';
    cout << endl;
    
    // 翻转 string
    string s = "abcd";
    reverse(s.begin(), s.end());
    cout << s << endl;  // dcba
    
    // 翻转数组
    int b[] = {
    
    1, 2, 3, 4, 5};
    reverse(b, b + 5);
    for (int x : b) cout << x << ' ';
    cout << endl;
    
    return 0;
}

unique

/*
  返回去重之后的尾迭代器(或指针),仍然为前闭后开,即这个迭代器是去重之后末尾元素的下一个位置。
  该函数常用于离散化,利用迭代器(或指针)的减法,可计算出去重后的元素个数。
*/
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main() {
    
    
    
    // 数组去重
    int a[] = {
    
    1, 1, 2, 2, 3, 3, 4};
    int m = unique(a, a + 7) - a;  // 不同元素的个数
    cout << m << endl;  // 4
    for (int i = 0; i < m; i++) cout << a[i] << ' ';
    cout << endl;
    
    // vector去重
    vector<int> b = {
    
    1, 1, 2, 2, 3, 3, 4};
    b.erase(unique(b.begin(), b.end()), b.end());
    for (auto x : b) cout << x << ' ';
    cout << endl;
    
    return 0;
}

random_shuffle

#include <iostream>
#include <vector>
#include <algorithm>
#include <ctime>

using namespace std;

int main() {
    
    
    
    // 设置随机种子,使得每次结果不同
    srand(time(0));
    
    // 打乱数组
    int a[] = {
    
    1, 2, 3, 4, 5};
    random_shuffle(a, a + 5);
    for (auto x : a) cout << x << ' ';
    cout << endl;
    
    // 打乱 vector
    vector<int> b({
    
    1, 2, 3, 4, 5});
    random_shuffle(b.begin(), b.end());
    for (auto x : b) cout << x << ' ';
    cout << endl;
    
    return 0;
}

sort

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

struct Rec {
    
    
    int x, y;
    bool operator< (const Rec &t) const {
    
      // 方式(2)
        return x < t.x;
    }
} r[5];

bool cmp(Rec a, Rec b) {
    
      // 返回值为:a是够应该排在b的前面
    return a.x < b.x;
}

int main() {
    
    
    
    // 对数组排序
    int a[] = {
    
    3, 1, 4, 5, 2};
    sort(a, a + 5);  // 升序排列
    for (int x : a) cout << x << ' ';
    cout << endl;
    sort(a, a + 5, greater<int>());  // 降序排列
    for (int x : a) cout << x << ' ';
    cout << endl;
    
    // 对 vector 进行排序
    cout << "=======================" << endl;
    vector<int> t({
    
    3, 1, 4, 5, 2});
    sort(t.begin(), t.end());  // 升序排列
    for (int x : t) cout << x << ' ';
    cout << endl;
    sort(t.begin(), t.end(), greater<int>());  // 降序排列
    for (int x : t) cout << x << ' ';
    cout << endl;
    
    // 对结构体进行排序
    // 两种方式:(1) 传入比较函数; (2) 重载运算符
    cout << "=======================" << endl;
    for (int i = 0; i < 5; i++) r[i] = {
    
    -i, i};
    // 方式(1)
    sort(r, r + 5, cmp);
    for (int i = 0; i < 5; i++) printf("(%d, %d) ", r[i].x, r[i].y);
    cout << endl;
    // 方式(2)
    sort(r, r + 5);
    for (int i = 0; i < 5; i++) printf("(%d, %d) ", r[i].x, r[i].y);
    cout << 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[] = {
    
    1, 2, 4, 5, 6};
    int *p = lower_bound(a, a + 5, 4);  // 返回大于等于4的最小元素
    cout << *p << endl;  // 4
    int t = upper_bound(a, a + 5, 4) - a;  // 返回大于4的最小元素
    cout << a[t] << endl;  // 5
    
    // vector
    cout << "=======================" << endl;
    vector<int> b = {
    
    1, 2, 4, 5, 6};
    t = lower_bound(b.begin(), b.end(), 4) - b.begin();
    cout << b[t] << endl;  // 4
    t = upper_bound(b.begin(), b.end(), 4) - b.begin();
    cout << b[t] << endl;  // 5
    
    return 0;
}

nth_element

#include <iostream>
#include <algorithm>

using namespace std;

int main() {
    
    
    
    // 数组
    int a[] = {
    
    6, 2, 1, 4, 3, 5};
    int k = 2;  // a[2]已经被排到正确的位置上(递增序),第三小的数
    nth_element(a, a + k, a + 6);
    cout << a[2] << endl;  // 3
    for (int x : a) cout << x << ' ';
    cout << endl;
    
    // vector
    cout << "=======================" << endl;
    vector<int> b = {
    
    6, 2, 1, 4, 3, 5};
    auto kptr = b.begin() + 2;  // a[2]已经被排到正确的位置上(递增序),第三小的数
    nth_element(b.begin(), kptr, b.end());
    cout << *kptr << endl;  // 3
    for (int x : b) cout << x << ' ';
    cout << endl;
    
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_42638946/article/details/113922374