内容提要

STL


 

 

STL

 

首先,拒绝两个问题:

  • 这东西我自己也能写吖
  • 这东西怎么写吖(比如STL的sort是七八个排序放一块的...)

 

Pair

#include<utility>
using namespace std;
pair<typename1,typename2> variablename;

pair<int,int> x;
pair<double ,double> y;
pair<int,double> z;
pair<pair<int,int>int>a;

作为需要返回多个量的函数返回值

作为结构体的代替

比较大小:先比较第一个元素,如果相同再比较第二个,以此类推

String

string a;

#include <string>
using namespace std;
string a;

作为字符串数组的替代

可以赋值

a = b,a = "hello word"

a[i]:支持下表访问

a.size()字符串长度

a+b:字符串拼接

vector

有编号为1到3000*3000的人,每个人都属于一个队伍,一共有3000个队伍,每个队伍可能有任意多数人,也可能没有人,如何存数?

const int maxN = 3000;
const int maxM = 3000 * 3000;
int team[maxN][maxM];

 

 

 

 

 

 

vector:不定长数组:不需要指定数组元素的数量,可以直接通过元素的个数分配内存

#include <vector>
using namespace std;
vector<TypeName> VariableName;
vector<int> a;
vector<double> b;
vector<vector<int> > c;

 

a[0]:随机下标访问

a.push_back():在末尾插入一个元素

a.pop_back:弹出末尾元素

a.front():访问第一个元素

a.back():访问最后一个元素

a.clear():清空一个vector

a.empty():返回vector是否为空

a.size():返回vector总元素的个数

以上的除了清空vector复杂度为O(n),其他均为O(1)

工作原理:每当你添加第2^n +1个元素时,就开一个连续的2^(n+1)的内存来存储

但是由于他每次要分配内存,所以会慢一些

样例:接受n个整数的输入,倒序输出

#include <iostream>
using namespace std;
int main() {
  vector<int> a;
  int n, x;
  cin >> n;
  for (int i = 0; i < n; ++i) {
    cin >> x;
    a.push_back(x);
  }
  while (!a.empty()) {
    cout << a.back();
    a.pop_back();
  }
  return 0;
}

 

迭代器

vector<int>::iterator it;

迭代器(iterator)的作用类似于指针,是一个指明元素位置的量。什么类型的vector就要用什么位置的迭代器

a.begin():返回第一个元素的迭代器

a.end():返回最后一个元素的后一个迭代器(因为左闭右开嘛)

*a.begin():等价于a.front()

*it:得到it指向的值

it++:得到下一个位置的迭代器

it+=i:得到下i个位置的迭代器,时间复杂度O(1)

it1 - it2:得到it1和it2之间的元素个数

遍历vector:

int main()
{
    for(auto x:a)
    {
    
    }
    //遍历 
}

 

set:

集合:不能有重复元素+有序性

#include <set>
using namespace std;
set<TypeName> VariableName;
set<int> a;
set<double> b;

 

set的底层使用红黑树这个数据结构来维护集合

a.begin():第一个元素的迭代器

a.end():最后一个元素的后一个迭代器

a.insert():插入一个元素 O(log n)

a.erase():删除一个元素 O(log n)

a.find():寻找一个元素 O(log n)

a.count():查找某个元素的数量 O(log n)

a.lower_bound():查找大于等于某个值的第一个元素 O(log n)

a.upper_bound():查找大于某个值的第一个元素 O(log n)

a.equal_range():查找等于某个值的左闭右开区间,返回一个pair O(log n)

#include <set>
#include <iostream>
using namespace std;
int main() {
    set<int> a;
    a.insert(1); // a: {1}
    a.insert(1); // a: {1}
    a.insert(2);remove: {1, 2}
    a.erase(1); // a: {2}
    for (int i = 0; i < 5; ++i) {
        a.insert(i);
    } // a: {0, 1, 2, 3, 4}
    cout << a.size() << endl; // 5
    cout << a.count(4) << endl; // 1
}

Set 的迭代器和 Vector 的不同。

set<int>::iterator it;

• *it: it 的求值

• ++it: it 的下一个迭代器

• --it: it 的前一个迭代器

• Vector: 随机访问迭代器

• Set: 双向迭代器

它并不滋兹减法

重载运算符:

 

struct Student {
  int grade;
  char name[20];
}
  bool operator <(Student a, Student b) {
  return a.grade < b.grade;
}

或者也可以这么写

struct Student {
    int grade;
    char name[20];
    bool operator <(Student b) {
        return grade < b.grade;
    }
}

MultiSet

#include <set>
using namespace std;
multiset<TypeName> VariableName;
multiset<int> s;

multiset 和 set 大部分操作相同,但支持在一个 set 内有多个元素。

注意在 multiset 中,如果 erase 一个数,仍然会把全部的数字删除。

Map

Problem

给出许多学生的名字和成绩,要求使用名字找到成绩。

比如学生 __debug 的微积分 59 分,我们希望能通过 __debug 找到 59.

a['__debug'] = 59 ?

#include <map>
using namespace std;
map<TypeName1, TypeName2> VariableName;
map<string, int> a;

 map 的本质就是一个元素为 pair 的 set,重载了 [] 运算符。

stack栈

#include <stack>
using namespace std;
stack<TypeName> VariableName;
stack<int> a;

一个“先进后出”结构。

a.size()

a.empty()

a.top(): 访问栈顶元素

a.pop(): 弹出栈顶

a.push(): 压入一个元素

queue队列

#include <queue>
using namespace std;
queue<TypeName> VariableName;
queue<int> a;

一个“先进先出”结构。

一个类似队列的结构。不同的是,队列每次出最先进队的元素,优先队列每次出最大的元素

类似 Set,需要重载 < 运算符

a.size()

a.empty()

a.top(): 访问堆顶

a.pop(): 弹出堆顶

a.push(): 向堆中加入一个元素

当然也可以不用

priority_queue<int ,vector<int>,less<int> > q;//大根堆
priority_queue<int ,vector<int>,greater<int> > q;//小根堆

或者这样

struct cmp
{
    bool operator()(int x,int y)
    {
        return x<y;
    }
}
priority_queue<int ,vector<int>,cmp > q;

Algorithm
Sort

#include <algorithm>
using namespace std;
int a[30];
vector<int> b;
int main() {
  sort(a, a + 30);
  sort(b.begin(), b.end());
}

Reverse

#include <algorithm>
using namespace std;
int a[30];
vector<int> b;
int main() {
    reverse(a, a + 30);
    reverse(b.begin(), b.end());
}

unique
去重(必须要是排序好了的数列)

fill(把头到尾覆盖某个数)

int main
{
    sort(a,a+10);
    for(int i=0;i<10;i++)
        cout<<a[i]<<" ";
    cout<<endl;

    fill(unique(a,a+10),a+10,0)

    for(int i=0;i<10;i++)
        cout<<a[i]<<" ";
}

 

 

Next Permutation

int a[4] = {1, 2, 3, 4};
int
main() { do { for(int i=0;i<4;++i) cout<<a[i]<<" "; cout<<endl; }while(next_permutatiom(a,a+4)); }

 

寻找全排列

要求数组中元素可以比较。

均摊复杂度 O(1),单次运算交换次数不超过distance(Ai; Ai+1)/2, Ai; Ai+1 分别为第 i, i + 1 个排列,但是如果列出全排列的话就是O(n!)

 

Nth Element

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
int main()
{
    std::vector<int> v{5, 6, 4, 3, 2, 6, 7, 9, 3};
    std::nth_element(v.begin(), v.begin() + v.size()/2, v.end());
    std::cout << "The median is " << v[v.size()/2] << '\n';
    std::nth_element(v.begin(), v.begin()+1, v.end(),             
    std::greater<int>());
    std::cout << "The second largest element is " << v[1] << '\n';
}

复杂度O(n)

只让中间那个放在正确的位置,比他大的在前面,比他小的在后面

 

Random Shuffle

#include <random>
#include <algorithm>
#include <iterator>
#include <iostream>
int main()
{
    std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    std::shuffle(v.begin(), v.end(), g);
}

 

相关文章:

  • 2022-02-08
  • 2022-01-01
  • 2021-10-23
  • 2021-06-09
  • 2022-01-05
  • 2021-05-26
  • 2022-01-05
  • 2021-10-22
猜你喜欢
  • 2021-12-24
  • 2022-02-18
  • 2021-09-05
  • 2021-08-06
  • 2021-08-12
  • 2021-06-14
  • 2022-01-02
相关资源
相似解决方案