1.vector的常见用法详解
2.set的常见用法详解
3.map的常见用法详解
map的常见用途
- 需要建立字符(或字符串)与整数之间映射的题目,使用map可以减少代码量
- 判断大整数或者其他类型数据是否存在的题目,可以把map当bool数组用
- 字符串和字符串的映射也有可能会遇到
(1)通过迭代器访问
//通过迭代器访问
#include <stdio.h>
#include <map>
using namespace std;
int main()
{
map<char, int> mp;
mp['m'] = 20;
mp['r'] = 30;
mp['a'] = 40;
for (map<char, int>::iterator it = mp.begin(); it != mp.end(); it++)
{
printf("%c %d\n", it->first, it->second);
}
system("pause");
return 0;
}
输出结果
a 40
m 20
r 30
map会以键从下到大的顺序自动排序,即按a<m<r的顺序排列着三对映射。这是由于map内部是使用红黑树实现的(set也是),在建立映射的过程中会自动实现从小到大的排序功能。
(2)find(),erase()
#include <stdio.h>
#include <map>
using namespace std;
int main()
{
map<char, int> mp;
mp['a'] = 1;
mp['b'] = 2;
mp['c'] = 3;
//返回键为key的映射的迭代器
map<char, int>::iterator it = mp.find('b');
//删除单个元素
mp.erase(it);//删除b 2
for (map<char, int>::iterator it = mp.begin(); it != mp.end(); it++){
printf("%c %d\n", it->first, it->second);
}
system("pause");
return 0;
}
输出结果
a 1
c 3
4.queue的常见用法详解
当需要实现广度优先搜索时,可以不用自己手动实现一个队列,而是用queue作为代替,以提高程序的准确性。
另外一点需要注意的是,使用front()和pop()函数前,必须用empty()判断队列是否为空,否则可能因为队空而出现错误。
STL容器中还有两种容器跟队列有关,分别是双端队列(deque)和优先队列(priority_queue),前者是首尾皆可插入和删除的队列,后者是使用堆实现的默认将当前队列最大元素置于队首的容器。
(1)push(),front(),back()
#include <stdio.h>
#include <queue>
using namespace std;
int main()
{
queue<int> q;
for (int i = 1; i <= 5; i++)
{
q.push(i);//push(i)用于将i压入队列,因此一次入列1 2 3 4 5
}
//front()和back()分别获得队首元素和队尾元素
printf("%d %d\n", q.front(), q.back());
system("pause");
return 0;
}
输出结果
1 5
(2)pop()
#include <stdio.h>
#include <queue>
using namespace std;
int main()
{
queue<int> q;
for (int i = 1; i <= 5; i++)
{
q.push(i);
}
for (int i = 1; i <= 3; i++)
{
q.pop();//出队首元素三次(即依次出队1 2 3)
}
printf("%d\n", q.front());
system("pause");
return 0;
}
(3)empty()
#include <stdio.h>
#include <queue>
using namespace std;
int main()
{
queue<int> q;
if (q.empty() == true){//一开始队列内没有元素,所以是空
printf("Empty\n");
}
else{
printf("Not Empty\n");
}
q.push(1);
if (q.empty() == true){//一开始队列内没有元素,所以是空
printf("Empty\n");
}
else{
printf("Not Empty\n");
}
system("pause");
return 0;
}
(4)size()
#include <stdio.h>
#include <queue>
using namespace std;
int main()
{
queue<int> q;
for (int i = 1; i <= 5; i++)
{
q.push(i);
}
printf("%d\n", q.size());
system("pause");
return 0;
}
5.priority_queue的常见用法详解
(1)push(x),将x入队
#include <stdio.h>
#include <queue>
using namespace std;
int main()
{
priority_queue<int> q;
q.push(3);
q.push(4);
q.push(1);
printf("%d\n", q.top());
system("pause");
return 0;
}
输出结果
4
(2)pop(),令队首元素出队
#include <stdio.h>
#include <queue>
using namespace std;
int main()
{
priority_queue<int> q;
q.push(3);
q.push(4);
q.push(1);
printf("%d\n", q.top());
q.pop();
printf("%d\n", q.top());
system("pause");
return 0;
}
输出结果:
4
3
(3)优先级的设置
基本数据类型:
此处指的基本数据类型就是Int型、double型、char型等可以直接使用的数据类型,优先队列对它们的优先级设置一般是数字大的优先级越高,因此队首元素就是优先级队列内元素最大的那个(如果是char型,则是字典序最大的)。对基本数据类型来说,下面两种优先队列的定义是等价的。
priority_queue<int> q;
priority_queue<int,vector<int>,less<int> >q;
vector填写的是来承载底层数据结构堆(heap)的容器,如果第一个参数是double型或char型,则此处只需要填写vector或vector;而第三个参数less则是对第一个参数的比较类,less表示数字大的优先级越大,而greater表示数字小的优先级越大。
#include <stdio.h>
#include <queue>
#include <functional>
using namespace std;
int main()
{
priority_queue<int, vector<int>,greater<int> >q;
q.push(3);
q.push(4);
q.push(1);
printf("%d\n", q.top());
system("pause");
return 0;
}
输出结果:
1
结构体类型:
fruit结构体中增加了一个函数,其中“friend"是友元,函数内部为”return f1.price<f2.price",因此重载后小于号还是小于号的作用,其内部以价格高的水果为优先级高。
对于小于号的重载与排序函数sort中的cmp函数有些相似,它们的参数都是两个变量,函数内部都是return了true或false。事实上,这两者的作用确实是类似的,只不过效果上刚好相反。在排序中,如果是“return f1.price>f2.price",那么则是按价格从高到低排序,但是在优先队列中却是把价格低的放在队首。原因在于,优先队列本身默认的规则就是优先级高的放在队首,因此把小于号重载为大于号的功能时只是把这个规则反向了一下。优先队列的这个函数与sort中的cmp函数的效果是相反的。
#include <iostream>
#include <string>
#include <queue>
using namespace std;
struct fruit
{
string name;
int price;
friend bool operator < (fruit f1, fruit f2){
return f1.price > f2.price;
}
}f1,f2,f3;
int main()
{
priority_queue<fruit> q;
f1.name = "桃子";
f1.price = 3;
f2.name = "梨子";
f2.price = 4;
f3.name = "苹果";
f3.price = 1;
q.push(f1);
q.push(f2);
q.push(f3);
cout << q.top().name << " " << q.top().price << endl;
system("pause");
return 0;
}
输出结果:
苹果 1
把结构体写在外面,只需要把friend去掉,把小于号改成一对小括号,然后把重载的函数写在结构体外面,同时将其用struct包装起来。
#include <iostream>
#include <string>
#include <queue>
using namespace std;
struct fruit
{
string name;
int price;
}f1,f2,f3;
struct cmp{
bool operator() (fruit f1, fruit f2){
return f1.price > f2.price;
}
};
int main()
{
priority_queue<fruit, vector<fruit>, cmp> q;
f1.name = "桃子";
f1.price = 3;
f2.name = "梨子";
f2.price = 4;
f3.name = "苹果";
f3.price = 1;
q.push(f1);
q.push(f2);
q.push(f3);
cout << q.top().name << " " << q.top().price << endl;
system("pause");
return 0;
}
输出结果:
苹果 1
即便是基本数据类型或者其他STL容器(例如set),也可以通过同样的方式来定义优先级。
如果结构体内的数据较为庞大(例如出现了字符串或者数组),建议使用引用来提高效率,此时比较类的参数中需要加上“const"和”&“。
friend bool operator < (const fruit &f1,const fruit &f2){
return f1.price>f2.price;
}
bool operator () (const fruit &f1,const fruit &f2){
return f1.price>f2.price;
}
7.stack的常见用法详解
stack用来模拟实现一些递归,防止程序对栈内存的限制而导致程序运行出错。一般来说,程序的栈内存空间很小,对有些题目来说,如果用普通的函数来进行递归,一旦递归层数过深,则会导致程序的崩溃。如果用栈来模拟递归算法的实现,则可以避免这一方面的问题。
(1)push(x),将x入栈
#include <stdio.h>
#include <stack>
using namespace std;
int main()
{
stack<int> st;
for (int i = 1; i <= 5; i++)
{
st.push(i);
}
printf("%d\n", st.top());
system("pause");
return 0;
}
(2)top(),获得栈顶元素,pop(),弹出栈顶元素
#include <stdio.h>
#include <stack>
using namespace std;
int main()
{
stack<int> st;
for (int i = 1; i <= 5; i++)
{
st.push(i);
}
for (int i = 1; i <= 3; i++)
st.pop();
printf("%d\n", st.top());
system("pause");
return 0;
}
8.pair的常见用法详解
pair的常见用途
- 用来代替二元结构及其构造函数,可以节省编码时间
- 作为map的键值对来进行插入
(1)pair中元素的访问
#include <iostream>
#include <utility>
#include <string>
using namespace std;
int main()
{
pair<string,int> p;
p.first = "haha";
p.second = 5;
cout << p.first << " " << p.second << endl;
p = make_pair("xixi", 55);
cout << p.first << " " << p.second << endl;
p = pair<string, int>("heihei", 555);
cout << p.first << " " << p.second << endl;
system("pause");
return 0;
}
输出结果:
haha 5
xixi 55
heihei 555
(2)比较操作数
#include <cstdio>
#include <utility>
using namespace std;
int main()
{
pair<int, int> p1(5, 10);
pair<int, int> p2(5, 15);
pair<int, int> p3(10, 5);
if (p1 < p3) printf("p1<p3\n");
if (p1 <= p3) printf("p1<=p3\n");
if (p1 < p2) printf("p1<p2\n");
system("pause");
return 0;
}
输出结果:
p1<p3
p1<=p3
p1<p2
(3)作为map的键值对来进行插入
#include <iostream>
#include <string>
#include <map>
using namespace std;
int main()
{
map<string, int> mp;
mp.insert(make_pair("heihei", 5));
mp.insert(pair<string, int>("haha", 10));
for (map<string, int>::iterator it = mp.begin(); it != mp.end(); it++)
{
cout << it->first << " " << it->second << endl;
}
system("pause");
return 0;
}
输出结果:
haha 10
heihei 5