cpp笔记07:STL

STL

基本概念

STL(Standard Template Library,标准模板库)

STL从广义上分为:容器(container)算法(algorithm)迭代器(iterator)

容器算法之间通过迭代器进行无缝连接

STL几乎所有代码都采用了模板类或者模板函数

六大组件

容器,算法,迭代器,仿函数,适配器,空间配置器

1.容器:各种数据结构,如vector,list,deque,set,map等,用来存放数据

2.算法:各种常用算法,如sort,find,copy,for_each等

3.迭代器:扮演了容器与算法间的胶合剂

4.仿函数:行为类似函数,可作为算法的某种策略

5.适配器:一种用来修饰容器或者仿函数或迭代器接口的东西

6.空间配置器:负责空间的配置与管理

容器

常用数据结构:数组,链表,树,栈,队列,集合,映射表等

这些容器分为序列式容器关联式容器两种:

序列式容器:强调值的排序

关联式容器:二叉树结构,各元素见没有严格的物理上的顺序关系

算法

分为:质变算法非质变算法

质变算法:运算过程中会更改元素内容

非质变算法:不会改变

迭代器

提供一种方法,使之能够依序寻访某个容器所含的各个元素,又无需暴露该容器的内部表示方式。

每个容器都有自己专属的迭代器

容器

vector

初识

void myPrint(int val) {
    cout<<val<<endl;
}
void test() {
    vector<int> v; //创建vector容器
    //向容器中插入数据
    v.push_back(10);
    v.push_back(20);

    //通过迭代器访问容器中的数据
    //初学时可以把迭代器看成是指针
    vector<int>::iterator itBegin = v.begin(); //起始迭代器指向容器中第一个元素
    vector<int>::iterator itEnd = v.end(); //结束迭代器指向容器最后一个元素的下一个位置
    //第一种遍历方式
    while(itBegin!=itEnd) {
        cout<<*itBegin<<endl;
        itBegin++;
    }
    //第二种遍历方式
    for(vector<int>::iterator it = v.begin();it!=v.end;it++) {
        cout<<*it<<endl;
    }
    //第三种遍历方式
    //STL遍历算法
    for_each(v.begin(),v.end(),myPrint); //回调myPrint
}

vector数据结构与数组非常相似,也称为单端数组,不同之处在于数组是静态空间,而vector可以动态扩展

动态扩展:找一块更大的内存空间将原数据拷贝到新空间,释放原空间

常用方法
构造函数

vector<T> v,vector(v.begin,v.end) 将v[begin(),end())这个区间中的元素拷贝,vector(n,elem)将n个elem拷贝,vector(vec)拷贝构造

赋值

vector1=vector2;vector.assign(v.begin(),v.end())

容量和大小

vector.empty()     判断容器是否为空

vector.capacity()  返回容器容量

vector.size()        返回容器中元素个数

vector.resize()     重新指定容器长度,若容器变长以默认值填充新位置,若变短则末尾长处容器长度的元素删除

插入和删除

vector.push_back()           尾部插入元素

vector.pop_back()             删除最后一个元素

vector.insert(iterator,ele)   迭代器指向位置添加元素        

vector.erase(iterator)        删除迭代器指向的元素

vector.clear()                     删除容器中所有元素

数据存取

vector.at();vector[];vector.front() 返回第一个元素;vector.back()返回最后一个

互换容器

vector.swap(vec) vector与vec元素互换

用途:巧用swap可以收缩内存空间

预留空间

vector.reserve(len)  容器预留len个元素长度,预留位置不初始化,元素不可访问

用途:减少vector在动态拓展容量时的拓展次数

string

string和char*的区别

char*是一个指针,string是一个类,类内部封装了char*,管理这个字符串,是一个char*型容器。

常用方法
赋值

string = "",string.assign()

字符串拼接

string += "",string.append()

查找和替换

string.find(),string.rfind()

find是从左往右找,rfind是从右往左找

string.replace(start,n,s)s中从start开始的n个字符换为s

字符串比较

按字符串的ASCII码进行比较

=返回0,>返回1,<返回-1

string.compare()

字符串存取

string[],string.at()

插入删除

string.insert()

string.erase()

子串

string.substr(start,number)

deque

双端数组,可以对头和尾进行插入删除

与vector的区别:vector对于头部的插入删除效率低,deque相对而言对头部的插入删除速度比vector块,vector访问元素时的速度会比deque块,这和两者的内部实现有关

常用方法
构造函数

类似vector 

deque<T>deq; deque<T>deq(iterator1,iterator2);deque<T>deq(number,element);

deque<T>deq(deq2)

赋值

deque1=deque2;deque.assign()

容器和大小

deque.empty();deque.size();deque.resize()

deque没有容量的概念

插入和删除

deque.push_back();deque.push_front()头插;deque.pop_back();deque.pop_front头删

deque.insert();deque.clear();deque.erase()

数据存取

deque[];deque.at();deque.front();deque.back()

排序操作

sort(iterator1,iterator2)根据迭代器对区间元素进行排序

用的时候要包含头文件algorithm

小练习

//有5名选手ABCDE。10个评委分别对每一名选手打分,去最高最低,取平均
class Person {
public:
    Person(string name,int score) {
        this->name = name;
        this->score = score;
    }
    string name;
    int score;
};
void createPerson(vector<Person>&g) {
    string nameSeed = "ABCDE";
    for(int i=0;i<5;i++) {
        string name = "选手";
        name += nameSeed[i];

        int score = 0;

        Person p(name,score);
        g.push_back(p);
    }
}
void setScore(vector<Person> &g) {
    for(vector<Person>::iterator i=g.begin();i<g.end();i++) {
        //将评委的分数放到deque
        deque<int> d;
        for(int i=0;i<10;i++) {
            int score=rand()%41+60; //60-100
            d.push_back(score);
        }
        sort(d.begin(),d.end());
        d.pop_back();
        d.pop_front();
        int sum = 0;
        for(deque<int>::iterator i=d.begin();i<d.end();i++) {
            sum += *i;
        }
        i->score = sum/d.size();
    }
}

stack

概念:一种先进后出(first in last out,FILO)的数据结构,它只有一个出口

因为只有顶端元素才可被外界使用,所以栈不允许有遍历行为

常用方法
构造函数

stack<T>;stack(stk)

赋值

stack1=stack2

数据存取

push() 向栈顶存数据;pop() 从栈顶移除第一个元素;top() 返回栈顶元素

大小操作

empty() 判断堆栈是否为空;size() 返回栈的大小

queue

概念:queue是一种先进先出(First in First out,FIFO)的数据结构,有两个出口

队尾只能进数据,队头只能出数据

只有队头和队尾才可以被外界使用,因此队列不允许有遍历行为

常用方法
构造函数

queue<T> que;queue(que);

赋值

que1=que2

数据存取

push(ele) 往队尾添加ele;pop() 从队头移除一个元素;back() 返回队尾元素;front() 返回队头元素

大小操作

empty() 判断堆栈是否为空 size() 返回栈的大小

list(链表)

功能:将数据进行链式存储

数据域存放数据,指针域存放下一个数据的地址。方便对任意位置进行快速插入或删除元素

但是遍历速度没有数组块,占用空间比数组大

STL中的list是双向循环链表,前面数据的地址也存。最后一个节点的下一个节点地址记录的是第一个节点的地址,第一个节点记录的上一个节点的地址是最后一个节点的地址(与图片不符

list的迭代器只支持前移和后移属于双向迭代器

常用方法
构造函数

list<T> lst ; list(iterator1,iterator2) ; list(n,element) ; list(list1)

赋值和交换

list.assign(iterator1,iterator2);list.assign(n,elem)

list1 = list2;

list.swap(lst)  与lst元素互换

大小操作

list.size() ; list.empty() ; list.resize();

插入和删除

list.push_back(); list.pop_back() ; list.push_front() ; list.pop_front() ;

list.insert(pos,ele) ; list(pos,n,ele) ; list(pos,iterator1,iterator2) 插入数据在pos位置

list.clear(); list.erase(iterator1,iterator2) ; list.erase(pos) ;

list.remove(elem) 删除容器中所有与elem值向匹配的元素

数据存取

不可以用[ ]访问

list.front(); 返回第一个元素

list.back(); 返回最后一个元素

反转和排序

list.reverse(); 反转

list.sort(); 排序    sort(iterator1,iterator2)用不了 

所有不支持随机访问迭代器的容器,不可以用标准算法

set/multiset

所有元素都会在插入时自动被排序,属于关联式容器,底层结构是用二叉树实现

两者区别:set不允许有重复元素,multiset允许有重复元素

常用方法
构造函数
赋值
添加数据

set.insert()

大小和交换

set.empty() ; set.swap(set1) ; set.size();

删除

set.clear();set.erase()

查找和统计

set.find(ele) ; 查找ele元素是否存在若存在返回该元素的迭代器;不存在返回set.end()

set.count(ele) ; 统计ele元素的个数

排序

set默认从小到大排序,利用仿函数可以改变排序规则

//仿函数:是一个定义了一个含有重载()函数的类
class MyCompare {
public:
    bool operator()(int v1,int v2) const {
        return v1>v2;
    }
};

void test01() {
    //指定排序规则从大到小
    set<int,MyCompare> s2;   //在插入数据之前就要指定好排序规则 利用仿函数
    s2.insert(10);
    s2.insert(40);
    s2.insert(20);
    s2.insert(50);
    s2.insert(30);
    for(set<int,MyCompare>::iterator i=s2.begin();i != s2.end();i++) {
        cout<< *i << "";
    }
}

map/multimap

map中所有元素都是pair,pair的第一个元素为key,第二个元素为value。所有元素都会根据元素的键值自动排序。是关联式容器,底层用二叉树实现。

map不允许有重复key元素,multimap允许

常用方法
构造函数

map<T1,T2> m ;map<>m1(m2)

大小和交换

map.empty();map.size();map.swap()

插入和删除

map.insert(pair<T1,T2>(t1,t2))     

map.insert(make_pair(a,b))

//pair<T1,T2> 对组   获取第一个元素用 pair.first()第二个用pair.second()

map.clear();

map.erase(iterator) ;map.erase(iterator1,iterator2);map.erase(key)  

查找和统计

map.find(key)

map.count(key)

排序

map.sort()   //同样要修改排序规则利用仿函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值