标准模板库STL

1.1 什么是STL?
STL是C++标准程序库的核心,深刻影响了标准程序库的整体结构。STL由一些可适应不同需求的集合类(collection class),以及在这些数据集合上操作的算法(algorithm)构成。STL内的所有组件都由模板(template)构成,其元素可以是任意类型。STL是所有C++编译器和所有操作系统平台都支持的一种库。

1.2 STL内容介绍
(1)容器(Container) - 管理某类对象的集合
(2)迭代器(Iterator) - 在对象集合上进行遍历
(3)算法(Algorithm) - 处理集合内的元素
(4)容器适配器(container adaptor)
(5)函数对象(functor)

1.2.1 STL容器
1.STL容器元素的条件
·必须能够通过拷贝构造函数进行复制
·必须可以通过赋值运算符完成赋值操作
·必须可以通过析构函数完称销毁动作
·序列式容器元素的默认构造函数必须可用
·某些动作必须定义operator ==,例如搜寻操作
·关联式容器必须定义出排序准则,默认情况是重载operator <
·对于基本数据类型(int,long,char,double,…)而言,以上条件总是满足。

2.STL容器的共同操作

//1.定义和初始化
    vector<int> vec1;    //默认初始化,vec1为空
    vector<int> vec2(vec1);  //使用vec1初始化vec2
    vector<int> vec3(vec1.begin(),vec1.end());//使用vec1初始化vec2
    vector<int> vec4(10);    //10个值为的元素
    vector<int> vec5(10,4);  //10个值为的元素
//2.常用操作方法
    vec1.push_back(100);            //添加元素
    int size = vec1.size();         //元素个数
    bool isEmpty = vec1.empty();    //判断是否为空
    int max_size=vec1.max_size()    //-返回容器能容纳的最大元素数量
    cout<<vec1[0]<<endl;        //取得第一个元素
    vec1.insert(vec1.end(),5,3);    //从vec1.back位置插入个值为的元素
    vec1.pop_back();              //删除末尾元素
    vec1.erase(vec1.begin(),vec1.end());//删除之间的元素,其他元素前移
    cout<<(vec1==vec2)?true:false;  //判断是否相等==、!=、>=、<=...
    vector<int>::iterator iter = vec1.begin();    //获取迭代器首地址
    vec1.clear();                 //清空元素
    vec1.begin();                 //返回一个迭代器,指向第一个元素
    vec1.end();                   //返回一个迭代器,指向最后一个元素之后
    vec1.rbegin();                //返回一个逆向迭代器,指向逆向遍历的第一个元素
    vec1.rend();                  //返回一个逆向迭代器,指向逆向遍历的最后一个元素之后
//3.遍历
    //下标法
    int length = vec1.size();
    for(int i=0;i<length;i++)
    {
       cout<<vec1[i];
    }
    cout<<endl<<endl;
    //迭代器法
    vector<int>::const_iterator iterator = vec1.begin();
    for(;iterator != vec1.end();iterator++)
    {
       cout<<*iterator;
    }

1.4 STL迭代器
迭代器的作用:重载了*,++,==,!=,=运算符。用以操作复杂的数据结构,容器提供迭代器,算法使用迭代器;常见的一些迭代器类型:iterator、const_iterator、reverse_iterator和const_reverse_iterator,实例如下:

#include <iostream>
#include <vector>
using namespace std;
int main()
{
    vector<int> v;
    v.push_back(3);  //数组尾部插入3
    v.push_back(2);
    v.push_back(1);
    v.push_back(0);
    cout << " 下标 " << v[3] << endl;
    cout << " 迭代器 " << endl;
    for(vector<int>::iterator i = v.begin();i!= v.end();++i)
    {
        cout << *i << " ";
    }
    cout << endl;
    //在第一个元素之前插入111  insert begin+n是在第n个元素之前插入
    v.insert(v.begin(),111);
    //在最后一个元素之后插入222 insert end + n 是在n个元素之后插入
    v.insert(v.end(),222);
    for(vector<int>::iterator i = v.begin();i!= v.end();++i)
    {
        cout << *i << " ";
    }
    cout << endl;
 
    vector<int> arr(10);
    for(int i = 0; i < 10; i++)
    {
        arr[i] = i;
    }
    for(vector<int>::iterator i = arr.begin();i!= arr.end();++i)
    {
        cout << *i << " ";
    }
    cout << endl;
    //删除 同insert
    arr.erase(arr.begin());
    for(vector<int>::iterator i = arr.begin();i!= arr.end();++i)
     {
        cout << *i << " " ;
     }
    cout << endl ;
    arr.erase(arr.begin(),arr.begin()+5);
    for(vector<int>::iterator i = arr.begin();i!= arr.end();++i)
    {
        cout << *i << " " ;
    }
    cout << endl ;
    return 0 ;
 }

1.5 map/multimap容器
map/multimap基本概念
Map的特性是,所有元素都会根据元素的键值自动排序。
map不允许两个元素有相同的键值。我们不可以通过map的迭代器改变map的键值, 因为map的键值关系到map元素的排列规则,任意改变map键值将会严重破坏map组织。如果想要修改元素的实值,那么是可以的。

Multimap和map的操作类似,唯一区别multimap键值可重复。

map/multimap常用API

//map构造函数
map<T1, T2> mapTT;//map默认构造函数: 
map(const map &mp);//拷贝构造函数

//map赋值操作
map& operator=(const map &mp);//重载等号操作符
swap(mp);//交换两个集合容器

//map大小操作
size();//返回容器中元素的数目
empty();//判断容器是否为空

//map插入数据元素操作
c.insert(pos,e)    //在pos位置为起点插入e的副本,并返回新元素位置(插入速度取决于pos)
c.insert(e)        //插入e的副本,并返回新元素位置
c.insert(beg,end)  //将区间[beg,end]内所有元素的副本插入到c中

//map删除操作
clear();//删除所有元素
erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器。
erase(beg,end);//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
erase(keyElem);//删除容器中key为keyElem的对组。

//map查找操作
find(key);//查找键key是否存在,若存在,返回该键的元素的迭代器;/若不存在,返回map.end();
count(keyElem);//返回容器中key为keyElem的对组个数。对map来说,要么是0,要么是1。对multimap来说,值可能大于1。
lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器。
upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器。
equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器。

1.6 set/multiset
使用平衡二叉树管理元素
集合(Set)是一种包含已排序对象的关联容器。
必须包含的头文件#include
map容器是键-值对的集合,好比以人名为键的地址和电话号码。相反地,set容器只是单纯的键的集合。当我们想知道某位用户是否存在时,使用set容器是最合适的。
set中不允许key相同的元素,multiset允许key相同的元素

//set构造函数
set<T> st;//set默认构造函数:
mulitset<T> mst; //multiset默认构造函数: 
set(const set &st);//拷贝构造函数
//set赋值操作
set& operator=(const set &st);//重载等号操作符
swap(st);//交换两个集合容器
//set大小操作
size();//返回容器中元素的数目
empty();//判断容器是否为空
//set插入和删除操作
insert(elem);//在容器中插入元素。
clear();//清除所有元素
erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器。
erase(beg, end);//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
erase(elem);//删除容器中值为elem的元素。
//set查找操作
find(key);//查找键key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
count(key);//查找键key的元素个数
lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器。
upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器。
equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器。

1.7 pair 模板:
pair模板可以用于生成 key-value对

1.8 算法
常用:
1.count:
size_t count(InIt first, InIt last, const T& val);
计算[first,last) 中等于val的元素个数

2.count_if
size_t count_if(InIt first, InIt last, Pred pr);
计算[first,last) 中符合pr(e) == true 的元素 e的个数

3.min_element:
template
FwdIt min_element(FwdIt first, FwdIt last);
返回[first,last) 中最小元素的迭代器,以 “< ”作比较器

4.max_element:
template
FwdIt max_element(FwdIt first, FwdIt last);
返回[first,last) 中最大(不小)元素的迭代器,以 “< ”作比较器

5.for_each
template<class InIt, class Fun>
Fun for_each(InIt first, InIt last, Fun f);
对[first,last)中的每个元素 e ,执行 f(e) , 要求 f(e)不能改变e

6.find
template<class InIt, class T>
InIt find(InIt first, InIt last, const T& val);
返回区间 [first,last) 中的迭代器 i ,使得 * i == val

7.find_if
template<class InIt, class Pred>
InIt find_if(InIt first, InIt last, Pred pr);
返回区间 [first,last) 中的迭代器 i, 使得 pr(*i) == true

  1. binary_search 折半查找,要求容器已经有序且支持随机访问迭代器,返回是否找到
    template<class FwdIt, class T>
    bool binary_search(FwdIt first, FwdIt last, const T& val);
    上面这个版本,比较两个元素x,y 大小时, 看 x < y

template<class FwdIt, class T, class Pred>
bool binary_search(FwdIt first, FwdIt last, const T& val, Pred pr);
上面这个版本,比较两个元素x,y 大小时, 看 pr(x,y)

  1. lower_bound,uper_bound, equal_range
    lower_bound:
    template<class FwdIt, class T>
    FwdIt lower_bound(FwdIt first, FwdIt last, const T& val);
    要求[first,last)是有序的,
    查找大于等于val的最小的位置

10.sort 快速排序
template
void sort(RanIt first, RanIt last);
按升序排序。判断x是否应比y靠前,就看 x < y 是否为true
template<class RanIt, class Pred>
void sort(RanIt first, RanIt last, Pred pr);
按升序排序。判断x是否应比y靠前,就看 pr(x,y) 是否为true

11.改变序列的算法 unique
template
FwdIt unique(FwdIt first, FwdIt last);
用 == 比较是否相等
template<class FwdIt, class Pred>
FwdIt unique(FwdIt first, FwdIt last, Pred pr);
用 pr 比较是否等
去除[first,last) 这个升序序列中的重复元素
返回值是迭代器,指向元素删除后的区间的最后一个元素的后面

12.reverse
template
void reverse(BidIt first, BidIt last);
颠倒区间[first,last)顺序

在最近的学习中,又加上了关于文件的操作,明显感到比之前的学习更加困难了,面对这个之前从未接触过的内容,显得有些手足无措,一开始会为着这件事焦头烂额,但慢慢的就发现了自己的问题,还是对知识的掌握和运用能力不足,有时候上课会分心,还需要课下再去看回放,再去翻阅一下资料。要先把基础打好才,多写几个简单的小代码感受感受,熟悉一下再放到大的程序下,不要知识还没懂就想写程序,这也是不现实的。所以这真的我们课下下功夫去认真对待,多写写,多调调才有收获。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值