参考资料
https://zhuanlan.zhihu.com/p/363771232
http://c.biancheng.net/view/6749.html
http://www.cplusplus.com/reference/stack/stack/?kw=stack
https://www.nhooo.com/cpp/cpp-set-constructor.html
个人心得
什么叫算法?
每次计算的结果都是一段信息,所谓算法就是利用 信息的方法。
关联式容器的概念
STL 标准库中另一类容器,即,包括 map、multimap、set 以及 multiset 这 4 种容器。
和序列式容器不同的是,
关联式容器在存储元素时还会为每个元素在配备一个键,整体以键值对的方式存储到容器中。
相比前者,关联式容器可以通过键值直接找到对应的元素,而无需遍历整个容器。
另外,关联式容器在存储元素,默认会根据各元素键值的大小做升序排序。
相比其它类型容器,关联式容器查找、访问、插入和删除指定元素的效率更高。
注:set容器的键就是它要操作的对象
关于关联式容器的看法
关联式容器保存的 键+容器的底层结构 就是我们要利用的信息,
底层结构复杂 --> 键 信息量大 --> 算法复杂度低
但是
底层结构复杂 --> 维护 键和结构 的代价就高
基本操作
本文由 简悦 SimpRead 转码, 原文地址 zhuanlan.zhihu.com
队列 (queue)
基本操作
queue<type> a; //声明一个空队列
a.empty() //判断队列是否为空,如果为空则返回 1,不为空则返回 0
a.size() //返回队列元素个数
a.front() //返回指向队首元素
a.back() //返回指向队尾元素
a.push(t) //队尾插入元素
a.pop() //删除队首元素
优先队列
priority_queue <类型> a //声明一个空的优先队列
双端队列 (deque)
基本操作
deque<type> a; //声明一个空的双端队列
a.size() //获取队列元素个数
a.begin() //获取队首元素的迭代器
a.end() //获取队尾元素的迭代器
a.front() //获取队首元素
a.back() //获取队尾元素
a.push_back() //从队尾插入数据
a.push_front() //从队首插入数据
a.pop_back() //删除队尾数据
a.pop_front() //删除队首数据
a.empty() //判断队列是否为空
栈(stack)
stack<type> a;
a.empty(); //如果栈为空,返回true,否则返回false
a.size(); //返回栈中元素数目
a.top(); //返回指向栈顶元素的引用
a.push(t); //在栈顶插入x
a.pop(); // 删除栈顶元素
//栈和队列一样,没有clear之类的清空函数,如需清空一个栈,需要循环调用出栈函数
while (!a.empty()) a.pop();
向量 (vector)
vector <type> a;
vector <int> a(10); //初始化10个默认值为0的元素
vector <int> a(10,1); //初始化10个默认值为1的元素
vector<vector<int>> matrix; //初始化一个二维的vector
a.begin(); //取首元素的迭代器
a.end(); //取尾元素下一地址的迭代器
a.front(); //取首元素的值
a.back(); //取尾元素的值
a.push_back(); //往尾部添加元素
a.pop_back(); //删除尾部的元素
a.empty(); //判断是否为空
a.size(); //实际元素个数
a.reverse(iterator x,iterator y); //反转某段向量
a.clear(); //清空vector
a.insert(iterator it,x) //向迭代器it指向的元素前插入一个元素x
int t = a[n]; //下标形式访问向量
sort(a.begin(),a.end());
a.erase(unique(a.begin(),a.end()),a.end()); //去重
集合 (set)
自动去重并按照升序排序,只能通过迭代器访问
set<int> a; //初始化
set<int,greater<int>> a; //初始化降序排列
a.begin(); //返回指向第一个元素的迭代器
a.end(); //返回指向超尾的迭代器
a.clear(); //清空容器a
a.empty(); //判断容器是否为空
a.size(); //返回当前容器元素个数
a.count(x); //查询是否有元素x
a.insert(x); //插入元素
auto it = a.find(x); //查找x并返回迭代器
a.erase(x); //删除元素x,未找到不会报错
//注意,set不支持it < a.end()的写法
遍历:
for (auto it = a.begin();it!= a.end();it++) cout << *it << endl;
映射(map)
map 是一个键值对 (key/value) 容器,对于迭代器来说,可以修改 value,而不能修改 key。map 会根据 key 自动排序。
map<int,string> m; //定义一个空map m
m.count(k); //查询m中键值为k的元素是否存在
m.find(k); //存在则返回指向该元素的迭代器,否则返回结束地址end()
m.erase(k); //删除m中键为k的元素,返回删除元素的个数(1或0)
m.erase(p); //从m中删除迭代器p所指向的元素
m.insert(e); //e是一个用在用在m上的value_tpye类型的值(一个pair)
如果e.first不在m中,则插入一个值为e.second的新元素;如果该键在m中已存在,那么不进行任何操作
m.clear(); //清空map m
链表(list)
list<int>a{1,2,3}
list<int>a(n) //声明一个n个元素的列表,每个元素都是0
a.begin() //得到一个指向容器起始位置的iterator
a.end() //得到一个指向容器末端的下一位置的iterator
a.push_front() //将一个元素插入到头部
a.push_back() //将一个元素插入到尾部
a.empty() //判断是否为空
a.front() //获取头部元素
a.back() //获取尾部元素
a.pop_front() //删除头部元素
a.pop_back() //删除尾部元素
a.reverse(b.begin(),b.end()) //逆置
a.insert(a.begin(),100); //在a的头部插入100
a.erase(a.begin()); //将a的第一个元素删除
a.erase(a.begin(),a.end()); //将a的从begin()到end()之间的元素删除。
a.remove(t) //从list中删除t
增删可指定位置 的容器
Modifiers 修改器
操作 | vector | list |
---|---|---|
头插 | a.push_front() | |
尾插 | a.push_back() | a.push_back() |
指定位置插入 | a.insert(iterator it,x) | a.insert(iterator it,x) |
头删 | a.pop_front() | |
尾删 | a.pop_back() | a.pop_back() |
指定位置删除 | a.erase(iterator it) | a.erase(iterator it) |
指定元素删除 | a.remove(t) | |
清空 | a.clear() | a.erase(a.begin(),a.end()) |
改 | ||
排序 | sort(a.begin(),a.end()) | |
反转 | a.reverse(iterator x,iterator y) | |
去重 | a.erase(unique(a.begin(),a.end()),a.end()) |
Accessors 访问器
操作 | vector | list |
---|---|---|
取首迭代器 | a.begin() | a.begin() |
取尾元素下一地址的迭代器 | a.end() | a.end() |
取首元素 | a.front() | |
取尾元素 | a.back() | |
判空 | a.empty() | a.empty() |
下标访问 | int t = a[n] | |
取元素总数 | a.size() |
Constructors 构造器
操作 | vector | list |
---|---|---|
新建n个元素 | vector <T> v(n) | |
新建n个元素并初始化 | vector <T> v(n, value) | |
拷贝一段 | vector <T> v(a.begin(), a.end()) | list <T> l(a.begin(), a.end()) |
增删不可指定位置 的容器
Modifiers 修改器
操作 | set | map | queue | stack |
---|---|---|---|---|
插入元素 | a.insert() | a.insert() | a.push() | a.push() |
指定元素删除 | a.erase() | a.erase(key) | a.pop() | a.pop() |
清空 | a.clear() | a.clear() | ||
改 | ||||
排序 | ||||
反转 | ||||
去重 |
Accessors 访问器
操作 | set | map | queue | stack |
---|---|---|---|---|
取首迭代器 | a.begin() | a.begin() | ||
取尾元素下一地址的迭代器 | a.end() | a.end() | ||
取某元素迭代器 | a.find(val) | a.find(key) | ||
取首元素 | a.front() | a.front() | a.top() | |
取尾元素 | a.back() | a.front() | ||
判空 | a.empty() | a.empty() | a.empty() | a.empty() |
下标访问 | a[key] | |||
访问某元素 | a.at(key) | |||
求元素总数 | a.size() | a.size() | a.size() | a.size() |
查找元素的个数 | a.count(val) | a.count(key) |
Constructors 构造器
操作 | set | map | queue | stack |
---|---|---|---|---|
默认构造 | std::set<int> s1 | map<char,int> first | deque<int> first | stack<int> first |
复制构造 | set(const set& x) | map<char,int> third (second) | queue<int> second (first) | stack<int> second (first) |
范围构造 | int evens[] = {2,4,6,8};set<int> myset (evens, evens+5); | |||
迭代器构造 | set <int> fourth (second.begin(), second.end()) | map<char,int> second (first.begin(),first.end()) | ||
列表构造 | set<int> result ({1,2,3}) | queue<int> fourth ({1,3}) | stack<int> fourth ({1,3}) |
字符串 (string)
string 重载了很多运算符 + += <<= == !=>= >
//初始化
string a;
string str = "wdnmd";
//求长度
str.size();
//求子串
str.substr(n,m);
例: string a = "abc defg";
string b = a.substr(2,4); // b = "c de"
b = a.substr(2); // b = "c defg"
//插入字符串
string s1("Limitless"),s2("00");
s1.insert(2,"123"); //s1 = "Li123mitless"
s1.insert(3,s2); //s1 = "Li10023mitless"
//删除子串
string s1("real steel");
s1.erase(1,3); //s1 = "r steel"
s1.erase(5); //s1 = "r ste"
//查找操作
s.find(str) //查找字符串str在当前字符串s中第一次出现的位置
s.find(str,pos) //查找字符串str在当前字符串s中[pos.end]中第一次出现的位置
//用stl算法操作string对象
string s("afgcbed");
sort(s.begin(),s.end()); //abcdefg
next_permutation(s.begin(),s.end()); //abcdegf
reverse(s.begin(),s.end()); //fgedcba
//利用transform转换大小写
transform(A.begin(),A.end(),A.begin(),::toupper);
transform(B.begin(),B.end(),B.begin(),::tolower);