【留档】谈谈一些常见的STL用法
前言
STL大法好!!
今天来给大家介绍一下大家可能会需要用到的一些STL。
可能会讲不全,见谅因为我太菜,所以不光会讲不全,还会讲的浅(bushi
在这里,我们只讨论它们的用法,而不讨论更深层次的东西比如原理之类的。
那我们开始吧。
关于一些定义
容器:各种数据结构,比如 vector 就是一个容器。
算法:比如 sort(排序算法),find(查找算法)等,大多可以直接用。
迭代器:扮演了容器与算法之间的胶合剂,共有五种类型,从实现角度来看,迭代器是一种将operator* , operator-> , operator++,operator–等指针相关操作予以重载的class template. 所有STL容器都附带有自己专属的迭代器,只有容器的设计者才知道如何遍历自己的元素。原生指针(native pointer)也是一种迭代器。(来源于某文章)
可以把它理解为容器特有的指针。
栈
栈包含在头文件 #include<stack>
这个东西也叫作后进先出表(FILO)
我觉得它就是让大家不用手写栈了哈哈哈哈哈哈哈。
//栈的成员函数
stack<int> q; //尖括号里面可以是你想要的任何类型
q.top(); //取出栈顶元素
q.pop(); //清除栈顶元素
q.size(); //返回当前栈内元素个数(容器大小)
q.push(); //向栈顶加入新的元素
q.empty(); //判断栈是否为空,空则返回1,否则返回0
队列
队列,又称先进先出表(FIFO)
队列分三种:普通队列,优先队列和双端队列,都包含在头文件 #include<queue>中
- 普通队列
就是普通的队列。
队列的成员函数:
queue<int> q; //尖括号里面可以是你想要的任何类型
q.front(); //取出队首元素
q.pop(); //清除队首元素
q.size(); //返回当前队列内元素个数(容器大小)
q.push(); //向队列加入新的元素
q.empty(); //判断队列是否为空,空则返回1,否则返回0
- 优先队列
优先队列,是一个可以自动排序的队列,实际上它相当于一个堆。
堆中存放的类型可以是 int,也可以是自己定义的。
priority_queue<int> q; <=> 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;//和上面声明小根堆的方法是等价的,这里只是展示写比较函数的方法。
struct node{ //方法二:重载小于符号(可以理解为重新定义小于符号)
int x,y,sum;
bool operator<(const node &xx) const{
return xx.sum<sum;
}
}t,tt;
priority_queue<node> q;
优先队列的成员函数:
priority_queue<int> q; 这里直接声明成小根堆了
q.top(); //取出队首元素,和普通队列不太一样
q.pop(); //清除队首元素
q.size(); //返回当前队列内元素个数(容器大小)
q.push(); //向队列加入新的元素
q.empty(); //判断队列是否为空,空则返回1,否则返回0
- 双端队列
我们知道,队列和优先队列都只能从后端插入,从前端取出。
你是不是觉得这样非常的不爽?你是不是想要一个两边都能插入和删除的队列?
今天,它来了。
它叫做双端队列,英文名叫 deque。
它的作用非常的大 (不过目前我只知道能用在单调队列)
它支持用数组访问队列中的元素,支持在中间插入一个新元素。
它的成员函数:
deque<int> q
q.front(); //取队首
q.back(); //取队尾
q.push_front(); //在队首插入新元素
q.push_back(); //在队尾插入新元素
q.pop_front(); //删除队首元素
q.pop_back(); //删除队尾元素
q.empty(); //判断队列是否为空
q.size(); //返回队列内元素个数
q.insert();
//insert(插入的位置起点,插入终点,插入的元素)
//insert(插入位置,插入元素)这个只在指定位置插入元素。
q.erase();//清除元素,写法与insert类似。
q.clear(); //一键清空
vector
vector,也可以叫做动态数组。
无需给它指定大小,它会动态的开空间。
这个东西有点多,多的可以单独开出一篇文章来写,所以在这里给出一篇文章,讲的挺好的。因为原文不见了,所以找的网上的转载。c++ vetcor
等有空在把这里补一下吧~
string
这个东西叫字符串,使用时须包含头文件 #include<string> 但在我的电脑好像不用也能编译成功?
这个可比字符数组(char[100])好用多了!
-
它是动态的
-
它可以通过下标访问字符串内的元素
-
两个字符串可以直接比较大小(按位比较)
-
可以使用成员函数 find 查找需要的字符/字符串。
-
...
总之就是好用。
- string 的成员函数
string s; //这样就是定义了一个名为 s 的字符串了。
s.swap(); //交换两个字符串的内容
s+=append() / s. push_back(); //在尾部添加字符
s.insert(); //插入字符
s.erase(); //删除字符
s.clear(); //删除全部字符
s.replace(); //替换字符
s+ //串联字符串
s.size() / s.length() //返回字符数量
s.empty() //判断字符串是否为空
s[ ] //存取单一字符(下标访问)
s.copy() //将某值赋值为一个C_string
c_str() //将内容以C_string返回
s.substr() //返回某个子字符串
查找函数
find(查找的起始位置,查找的终止位置,查找的字符/字符串) //查找
rbegin() rend() //逆向迭代器(建议弄懂了STL的一些东西再用)
==,!=,<,<=,>,>=,compare() //比较字符串
list
STL 还有双向链表(妈妈再也不用担心我不会用链表啦!)
使用时须包含头文件 #include<list>
和手写链表一样,它只支持顺序遍历,不支持下标访问。
但是你不需要手写链表了,这不很舒服?
list 的成员函数:
list<int> lis;
lis.insert(插入位置,插入元素); //在指定的位置前一个位置插入指定元素。
lis.erase();//清除元素,写法与insert类似。
lis.front(); //取首
lis.back(); //取尾
lis.push_front(); //在链表头部首插入新元素
lis.push_back(); //在链表尾部插入新元素
lis.pop_front(); //删除队首元素
lis.pop_back(); //删除队尾元素
lis.empty(); //判断队列是否为空
lis.size(); //返回队列内元素个数
lis.clear(); //一键清空
map
这个不叫地图!!!
这是一个 STL,里面是一颗红黑树。说白了,就是一个能按照关键字排序的数据结构。
使用时须包含头文件 #include<map>
map 能够建立起 key-value 两个值之间的一个对应关系。其中,key与value 可以是你想要的任何类型。它的功能类似于 hash。当然,你也可以把它当做一个哈希表来用。
但是,当数据大小
接下来讲讲怎么用。
- 创建一个 map
map<string,int> score; //建立map
//插入元素,建立对应关系
1、 score.insert(pair<string,int>("Li hua",10);
2、 score.insert(map<string,int>::value_type("Li hua",10);
3、 score["Li hua"]=10;
需要注意的是,当关键字已经存在时,insert 操作是无效的,而数组插入方式则会直接替换原来关键字所关联的值。
- map 的查找
if(score.find("Li hua");!=score.end()) cout<<iter->second<<endl;
else cout<<"Not find"<<endl;
// 这里也可以用迭代器。
find 函数会返回查找的元素所在的位置,找不到就返回尾指针 score.end()。借此可判断该关键字是否存在。
- 其他成员函数:
score.size(); //返回map的大小(元素个数)
swap(); //交换两个 map
score.clear() //删除所有元素
score.count() //返回指定元素(key)出现的次数。
score.erase() //删除元素
另外推荐一下这篇文章,我觉得讲得很好。初学的时候看的就是这篇。
set
使用前须包含头文件#include<set>
set 和 map 一样,里面都是一颗红黑树。
- set 的成员函数
set<int> s;
s.begin(); // 返回指向第一个元素的迭代器
s.end(); // 返回指向迭代器的最末尾处(即最后一个元素的下一个位置)
s.clear(); // 清除所有元素
s.count(); // 返回某个值元素的个数
s.empty(); // 如果集合为空,返回true
s.erase() //删除指定位置的元素
s.insert() //在指定位置插入元素
s.size() //返回容器中的元素个数
后话
关于反向迭代器