STL
STL
主要内容
- 容器, 算法, 迭代器
容器
- 数组
- 获取数组的长度
- int arr[] = {1, 2, 3};
- start = arr;
- end = arr + sizeof(arr) / sizeof(arr[0])
有哪些
- string(与Java中的String不同, string是可变容器)
- vector
- list
- map
- deque
- set
API特点
- 名称基本的上都是一样的
类型
序列容器
- 特点: 容器元素在容器中的位置是有进入容器的时间和地点决定的
- 容器
- vector
- API
- push_back()
- pop_back() 没有返回值
- empty()
- assign()
- erase(pos1, pos2)
- clear()
- begin(), end(), 返回迭代器
- rbegin(), rend() 逆序
- front() 第一个元素, back() 最后一个元素
- at()
- size()
- resize()
- reserve(size): 提前创建个数, 减少拷贝, 同于vector
v(size) - capacity()
- swap()这里有技巧, 可以shrink空间
- vector
(v).swap(v)这样v就shrink了
- vector
- 使用如下方式从一个数组中构造vector
- vector
v(arr, &arr[sizeof(arr[0])])
- vector
-
使用迭代器
vector<int> v; vector<int>::iterator start = v.begin(); vector<int>::iterator end = v.end(); while (start != end) { cout << *start << " "; ++start; } cout << endl;
-
自定义一个count算法
int MyCount(int *start, int *end, int v) { int count = 0; while (start != end) { if (*start == v) { ++count; } ++start; } return count; }
-
deque
- API
- push_front()
- pop_front()
- push_back()
- pop_back()
- insert()
- front()
- clear()
- at()
- resize()
- size()
- reserve()
- erase()
- begin()
- end()
- cbegin()
- cend()
- API
-
stack
- API
- push()
- pop()
- top()
- empty()
- API
-
queue
- API
- push()
- pop()
- front()
- back()
- empty()
- API
-
list(双向链表)
- API
- push_back()
- push_front()
- pop_back()
- pop_front()
- insert()
- front()
- back()
- erase()
- clear()
- remove(): 根据值删除
- size()
- empty()
- resize()
- API
-
set(基于树)
// greater函数对象在funcional(预定义函数对象)文件中 set<int, greater<int>> s; s.insert() // 是有这个操作 s.find() s.erase() s.lower_bound(5) // >= 5的迭代器 s.upper_bound(5) // <= 5的迭代器 s.equal_range(5) // 返回pair
-
pair创建的方式
pair<string, string>("", ""); make_pairt("", "");
-
map(基于树)
- API
- insert(pair<int, int>(1, 1))
- insert(make_pair(1, 1))
- insert(map<int, int>::value_type(1, 1))
- insert的返回pair, second是false表示失败
- 而[]函数则会覆盖原来key的值
- mymap[1] = 1;
- size()
- empty()
- API
-
string
- API
- size()
- assign(), =
- at() -> 抛异常, [] -> 程序挂
- c_str()
- append(), +=
- find(string, pos), find(char *, pos), 没有返回-1
- find(), rfind()
- replace(pos1, pos2, string)
- compare(), > -> 1, == -> 0, < -> -1
- substr(pos1, pos2)
- insert()
- erase(pos1, pos2)
- API
-
关联容器
算法(与容器独立)
- sort(begin, end, fp)->fp是一个回调函数, 如果返回true则交换
与容器的关系
- 算法与容器独立
- 同于容器的迭代器关联
类型
- 遍历
- 查找(find)
- 删除
- 统计(count)
迭代器
- 可以认为是指针
函数对象
- 一元函数对象(接受一个对象)
class Print {
public:
// 重载()
void operator()(const int &v) {
cout << v << " ";
}
};
- 二元函数对象(接受两个对象)
- 一元谓词: return bool
- 二元谓词: return bool
算法有哪些(必要的时候重载操作符[使用的是自己定义的类, 内置的类型已经重写了, 并且在funciontal中有了greater, less等预定义函数对象])
-
find_if
- find
- find_if
- binary_search: 返回bool
- adjust_search: 相邻重复元素查找, 返回第二个重复的元素的位置
-
for_each
- 返回时一个函数对象, 注意, for_each的第三个参数不是引用, 所以在for_each中迭代的不会是我们传入的函数对象而是他的拷贝构造, 所以for_each才会返回一个函数对象
-
sort
- list容器不能使用sort, 所以list自己提供了sort算法, 因为list不能支持随机访问
- merge, 两个容器需要有序的
- random_shuffle
-
transform
-
count
- count
- count_if
-
拷贝与替换算法
- copy
- replace
- replace_if
-
max, min
-
distance, 可以将迭代器转为下标
其他算法numberic
-
accumulte
-
fill
-
代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class MyPrint {
public:
void operator()(const int &v) {
cout << v << " ";
}
};
void TestForEach() {
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8};
vector<int> v(arr, arr + sizeof(arr) / sizeof(int));
for_each(v.begin(), v.end(), MyPrint()); // 匿名一元函数对象
}
class MyComp {
public:
bool operator()(const int &a) {
return a > 7;
}
};
void TestFindIf() {
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8};
vector<int> v(arr, arr + sizeof(arr) / sizeof(int));
vector<int>::iterator pos = find_if(v.begin(), v.end(), MyComp()); // 匿名一元谓语函数对象
if (pos == v.end()) {
cout << "没有找到符合条件的元素" << endl;
return;
}
cout << *pos << endl;
}
class MyTransform {
public:
int operator()(const int &v1, const int &v2) {
return v1 + v2;
}
};
void TestTransform() {
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8};
vector<int> v1(arr, arr + sizeof(arr) / sizeof(int));
vector<int> v2(v1);
vector<int> v3(5);
transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), MyTransform());
for_each(v3.begin(), v3.end(), MyPrint());
}
class MySort {
public:
bool operator()(const int &a, const int &b) {
return a < b;
}
};
void TestSort() {
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8};
vector<int> v1(arr, arr + sizeof(arr) / sizeof(int));
cout << v1.size() << endl;
cout << "==============" << endl;
sort(v1.begin(), v1.end(), MySort());
for_each(v1.begin(), v1.end(), MyPrint());
}
int main() {
//TestForEach();
//TestFindIf();
//TestTransform();
TestSort();
return 0;
}
函数适配器
- 类似于Python中的参数绑定
- bind1st, bind2ed, not1, not2(取反)
// 注意binary_function的泛型好像不能够传入引用
class MyPrint : public binary_function<int, int, void> {
public:
void operator()(int a, int b) const{
if (a > b) {
cout << a << " ";
}
}
};
使用
for_each(begin, end, bind1st(MyPrint(), 1))
其他
- map中key自定义需要重载<函数, 有两个const