ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

清北学堂2019.5.3

2019-05-05 08:52:14  阅读:234  来源: 互联网

标签:std int 2019.5 元素 namespace 学堂 vector 清北 include


Day 6(文泓宇【a little sister】)

今天讲的是有关OI中的STL库:

首先,拒绝两个问题:
• 这东西我自己也能写啊?
• 这东西怎么写啊?

STL:

pair(自带排序【以第一关键字排序,以此类推】):

algorithm库包括了utility库

实例代码:

#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;

1.作为需要返回多个量的函数返回值
2.作为 struct 的替代
  Pair 的比较大小:先比较第一个元素,第一个元素相同时再比
较第二个元素。
  如果两个元素都相等则判定相等。
string(保证连续的2n的内存):

  作为字符串数组的替代:

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

各种用法:

• a = b, a = ``Hello World'': 支持赋值
• a[i]: 支持下标访问
• a.size(): 字符串长度
• a + b: 支持字符串拼接
• a > b: 支持按字典序排序
• a.substr(x, y): 从 x 位置开始,返回长度为 y 的子串

vector:

在空间需求很紧时不要用Vector

引入:

Problem 1
有编号为 1 到 3000 × 3000 的人,每个人都属于一个队伍。一共有
3000 个队伍,每个队伍 3000 人。如何存储这些数据?

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

Problem 2

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

const int maxN = 3000;
const int maxM = 3000 * 3000;
int team[maxN][maxM]; // Memory Limit Exceeded!

 

 

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

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

成员函数:

• a[0]: 随机下标访问, O(1).
• a.push_back(): 在末尾插入一个元素, O(1).
• a.pop_back(): 弹出末尾元, O(1).
• a.front(): 访问第一个元素(引用) , O(1).
• a.back(): 访问最后一个元素, O(1).
• a.clear(): 清空一个 Vector, O(n).
• a.empty(): 返回 Vector 是否为空, O(1).
• a.size(): 返回 Vector 中元素的个数, O(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 之间的元素个数, O(1)

vector<int>::iterator it;
for (it = a.begin(); it != a.end(); ++it)
{     cout << *it << endl; }

C++11:
auto(十分高端)【遍历vector】

#include<vector>
using namespace std;
vector <int >a;
int main()
{
          for(auto x: a)
          {
           }          
}

set:

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

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

• a.clear(): 清空元素
• a.empty(): 检查是否为空
• a.size(): 查看 set 内元素个数

替罪羊,Splay,Treap等等······(树结构)

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)

Erase一个不存在的数,将不会执行该语句

具有鲁棒性

#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); // a: {1, 2}
a.remove(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.

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

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

//这两行相同
map<string,int>a;
set<pair<string,int> >a;

Stack (能不用就不用):

一个先进后出的结构【FILO】

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

 

其成员函数为:

• a.size()
• a.empty()
• a.top(): 访问栈顶元素
• a.pop(): 弹出栈顶
• a.push(): 压入一个元素

Queue(这个好像十分的实用):

一个先进先出的结构【FIFO】

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

 

其成员函数有:

• a.size()
• a.empty()
• a.front(): 访问队首元素
• a.pop(): 弹出队首
• a.push(): 在队末尾加入一个元素

Priority Queue(优先队列):

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

与set相类似,需要重载<运算符

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

 

其成员函数有:

• a.size()
• a.empty()
• a.top(): 访问堆顶
• a.pop(): 弹出堆顶
• a.push(): 向堆中加入一个元素

Algorithm库

Sort:

是对于一个数列进行排序(默认从小到大)【若想要其他排列可以自己写了之后加入sort当中】

例如:

sort(a+1,a+n+1,cmp);

这里的cmp就需要自己去写

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

 

Reverse:

就是个反的sort

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

 

Unique(去重)【必须作用在有序的上】

将多余的全部清零的步骤:

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

 

区分:

  Fill是赋值

  Memset是清空

Next Permutation:

要求数组中元素可以比较。
均摊复杂度 O(1),单次运算交换次数不超过
distance(Ai,Ai+1)/2, Ai; Ai+1 分别为第 i, i + 1 个排列。

int a[] = {1, 2, 3, 4};
do {
...
} while (!next_permutation(a, a + 5));

 

再往后的就是一些神奇的东西了(我听的一懵一懵的TAT)

Binary Search 【有一点像二分查找】(要求有序):

#include <iostream>
#include <algorithm>
#include <vector>
int main()
{
  std::vector<int> a {1, 3, 4, 5, 9};
  std::vector<int> b {1, 2, 3};
  for (auto x : b) {
    if (std::binary_search(a.begin(), a.end(), x)) {
      std::cout << "Found " << needle << '\n';
    }  
    else {       std::cout << "no dice!\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';
}

 

Random Shufe:

#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);
}

标签:std,int,2019.5,元素,namespace,学堂,vector,清北,include
来源: https://www.cnblogs.com/gongcheng456/p/10805028.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有