C++——STL入门

简介: C++——STL入门

c++标准库包含STL,STL包含六大部件


STL

standard template library 标准模板库

C++的含义:C语言+类+模板

STL有6大组件:

容器、算法、迭代器、适配器、分配器、仿函数

容器(container)

  1. 系统封装好的数据结构
  2. 泛型编程思想,每种数据结构都能装任意类型
  3. 主要是对数据结构增删改查的操作

算法(algorithm)

  1. 系统封装好的算法(如sort排序算法)
  2. 一个算法适用多种容器(泛型编程思想)

迭代器(Iterator)

迭代器相当于指针

迭代器告诉算法要执行的范围(在容器中)

分配器(allocator)

对容器的内存进行管理分配(例如vector容器的自动扩充,自动缩容等)

仿函数(functor)

仿函数:结构体或类要实现函数的功能,就要重载function call 操作符 ()

#include <iostream>

usingnamespacestd;

classStu{

public:

   //重载()操作符

   //只有函数返回true时,a的优先级才大于b

   booloperator () (inta,intb){

       

       returna>b; //此时当a>b时返回true,那么数值越大优先级越高

       

       //return a<b; 此时当a<b时返回true,那么数值越小优先级越高

   }

};

intmain()

{

    Stus;

    cout<<s(1,2) <<endl;//0

    cout<<s(2,1) <<endl;//1

   return0;

}

容器(container)

容器类自动申请和释放内存,无需new和delete操作


结构及分类

Sequence Containers

序列式容器:按照放入元素的顺序进行排列

Array:定长数组

Vector:不定长数组

Deque:双端队列

List:双向链表

Forward-List:单向链表

Associative Containers

关联式容器:元素是以键值对的形式存在(key/value),通过key可以快速查找,因此这种容器适合大量查找

关联式容器又分为Ordered Container和Unordered Container,即定序容器和不定序容器

定序容器:元素在容器内的位置是亘古不变的

不定序容器:元素在容器内的位置会随着时间的推移而发生变化

Ordered Container

定序容器:底部是红黑树,一种高度平衡的二分树,避免最差情况的发生(例如退化成链表)

Set:key不可以重复(set的key就是value,value就是key)

Multset:key可以重复

Map:key不可以重复

Multmap:元素可以重复

Unordered Container

不定序容器:底部是HashTable(HashTable中的链表不宜过长,避免查找忒慢)

Unordered Set

Unordered Multset

Unordered Map

Unordered Multmap

所有容器共有的操作

  1. 赋值(=):数组之间不可以赋值,相同类型容器之间可以
  2. begin():返回指向开头元素的迭代器
    end():返回指向末尾的下一个元素的迭代器
  3. size():返回容器内元素的个数
  4. empty():空返回true,不空返回false
  5. clear():清空容器(可以用来初始化)

vector(动态数组)

#include<vector>

构造函数

vector();

explicitvector(size_typecount);

vector(size_typecount, constType&value);

template<classInputIterator>

vector(InputIteratorfirst, InputIteratorlast);

vector<int>memo;//无参构造啥都不加

memo=vector<int>(n+1,-1); //初始化n+1个元素,即[0,n]都为-1

vector<string>board(n,string(n,'.'));//初始化n个元素,即[0,n-1]都为n个'.'的字符串

vector<int>v(10);//初始size为10,是动态数组,容量可以改变;int a[10]容量则不可以改变

访问元素

  1. 下标
  2. back():返回末尾元素的引用
  3. front():返回首元素的引用

增删改查

push_back():在末尾插入一个元素

pop_back():删除末尾元素

insert():某个迭代器位置插入元素

erase():删除某个迭代器或者区间的元素,返回最后被删除的迭代器

队列

#include<queue> //包含queue,deque,priority_queue

queue<int>q;

双端队列deque

既可以头出队,也可以尾出队

既可以头入队,也可以尾入队

优先队列

priority_queue<int>q;//默认大的元素先出队

priority_queue<int,vector<int>,greater<int>>q;//这样子小的元素先出队

栈stack

#include<stack>

stack<int> s;

  1. push():将新元素进栈
  2. pop():弹出栈顶元素
  3. top():访问栈顶元素

集合set

不含重复元素,默认从小到大排序

#include<set>

增删改查

增删改查时间复杂度都为O(log n)

  1. insert():插入元素
  2. erase(x):删除元素
  3. count():返回元素数量
  4. find(x):在set内存在值为x的元素会返回该元素的迭代器,否则返回end()
  5. 遍历不能使用下标,要用迭代器

set<int> s;

s.insert(3);

s.insert(2);

set<int>::iterator it;

for (it = s.begin(); it != s.end(); it++)

cout << *it << endl;

映射map

#include<map>

map<string,int> m;

m["string"]=1;//下标为字符串

迭代器(iterator)

迭代器是泛化的指针,每个容器基本都有迭代器

算法通过迭代器知道要处理数据的范围(在容器中)

迭代器实现遍历

int ia[6]={5,1,2,3,1,4};

vector<int> vi(ia,ia+6);

vector<int>::iterator it=vi.begin();

for(;it!=vi.end();++it){

cout << *it << endl;

}

因为每种容器的迭代器实现是不同的,因此我们声明一个迭代器变量的时候需要指明是属于谁的迭代器

vector<int>::iterator it=vi.begin();//it是vector的迭代器

但是这种方式比较麻烦,我们可以使用auto关键字来自动识别迭代器种类

int main()

{

int ia[6]={5,1,2,3,1,4};

vector<int> vi(ia,ia+6);

for(auto a : vi){

cout << a << endl;

}

return 0;

}

谓词(predicate)

谓词就是一个判断,只能返回bool类型

5种谓词模式

1. 函数(function)谓词

/*Function Predicate*/

bool isLarger (const std::string &s1, const std::string &s2) {

return s1.size() > s2.size();

}

......

std::stable_sort(sv.begin(), sv.end(), isLarger);

函数谓词使用时,只需要函数名,函数名代表函数地址,但函数名本质并不是函数地址

2. 函数对象(function object)谓词

函数对象谓词也叫仿函数(functor)谓词:在类或结构体中重载了函数调用符()

/*Function Object*/

class LargerString {

public:

bool operator() (const std::string& a, const std::string& b) {

return a.size() > b.size();

}

};

......

std::stable_sort(sv.begin(), sv.end(), LargerString());

因为他们是仿函数(不是真的函数),因此仿函数谓词在使用时,需要 类名+()结构体名+() 这种格式

3. 库定义的函数对象(library-defined function object)谓词

使用标准库定义的函数对象, 充当算法中的谓词, 包含在#include<functional>

std::stable_sort(sv.begin(), sv.end(), std::less<std::string>());

4. 函数指针(function pointer)谓词

5. Lambda表达式(lambda expression)谓词

常用的谓词是函数谓词,仿函数谓词(分为自定义的和标准库定义的)

一元谓词与二元谓词

  1. 如果operator()接收一个参数,叫一元谓词
  2. 如果operator()接收两个参数,叫二元谓词

//自己定义的一元函数谓词greater2

bool greater2(int a){

return a>2;

}

int main()

{

int ia[6]={5,1,2,3,1,4};

vector<int> vi(ia,ia+6);

cout << count_if(vi.begin(),vi.end(),greater2);//3

return 0;

}

//使用标准库定义好的仿函数谓词greater<int>()

int main()

{

int ia[6]={5,1,2,3,1,4};

vector<int> vi(ia,ia+6);

cout << count_if(vi.begin(),vi.end(),bind2nd(greater<int>(),2));//3

return 0;

}

count_if函数第三个参数需要的是一元谓词,但是greater仿函数是二元谓词,所以我们可以通过function adapter(binder)来绑定第二个参数为2,那么greater<int>()只需要一个参数


目录
相关文章
|
6月前
|
编译器 C++ 容器
【c++丨STL】基于红黑树模拟实现set和map(附源码)
本文基于红黑树的实现,模拟了STL中的`set`和`map`容器。通过封装同一棵红黑树并进行适配修改,实现了两种容器的功能。主要步骤包括:1) 修改红黑树节点结构以支持不同数据类型;2) 使用仿函数适配键值比较逻辑;3) 实现双向迭代器支持遍历操作;4) 封装`insert`、`find`等接口,并为`map`实现`operator[]`。最终,通过测试代码验证了功能的正确性。此实现减少了代码冗余,展示了模板与仿函数的强大灵活性。
174 2
|
6月前
|
存储 算法 C++
【c++丨STL】map/multimap的使用
本文详细介绍了STL关联式容器中的`map`和`multimap`的使用方法。`map`基于红黑树实现,内部元素按键自动升序排列,存储键值对,支持通过键访问或修改值;而`multimap`允许存在重复键。文章从构造函数、迭代器、容量接口、元素访问接口、增删操作到其他操作接口全面解析了`map`的功能,并通过实例演示了如何用`map`统计字符串数组中各元素的出现次数。最后对比了`map`与`set`的区别,强调了`map`在处理键值关系时的优势。
337 73
|
3月前
|
存储 安全 编译器
c++入门
c++作为面向对象的语言与c的简单区别:c语言作为面向过程的语言还是跟c++有很大的区别的,比如说一个简单的五子棋的实现对于c语言面向过程的设计思路是首先分析解决这个问题的步骤:(1)开始游戏(2)黑子先走(3)绘制画面(4)判断输赢(5)轮到白子(6)绘制画面(7)判断输赢(8)返回步骤(2) (9)输出最后结果。但对于c++就不一样了,在下五子棋的例子中,用面向对象的方法来解决的话,首先将整个五子棋游戏分为三个对象:(1)黑白双方,这两方的行为是一样的。(2)棋盘系统,负责绘制画面。
47 0
|
7月前
|
存储 缓存 C++
C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程
C++ 标准模板库(STL)提供了一组功能强大的容器类,用于存储和操作数据集合。不同的容器具有独特的特性和应用场景,因此选择合适的容器对于程序的性能和代码的可读性至关重要。对于刚接触 C++ 的开发者来说,了解这些容器的基础知识以及它们的特点是迈向高效编程的重要一步。本文将详细介绍 C++ 常用的容器,包括序列容器(`std::vector`、`std::array`、`std::list`、`std::deque`)、关联容器(`std::set`、`std::map`)和无序容器(`std::unordered_set`、`std::unordered_map`),全面解析它们的特点、用法
C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程
|
6月前
|
存储 分布式计算 编译器
C++入门基础2
本内容主要讲解C++中的引用、inline函数和nullptr。引用是变量的别名,与原变量共享内存,定义时需初始化且不可更改指向对象,适用于传参和返回值以提高效率;const引用可增强代码灵活性。Inline函数通过展开提高效率,但是否展开由编译器决定,不建议分离声明与定义。Nullptr用于指针赋空,取代C语言中的NULL。最后鼓励持续学习,精进技能,提升竞争力。
|
6月前
|
存储 算法 C++
【c++丨STL】set/multiset的使用
本文深入解析了STL中的`set`和`multiset`容器,二者均为关联式容器,底层基于红黑树实现。`set`支持唯一性元素存储并自动排序,适用于高效查找场景;`multiset`允许重复元素。两者均具备O(logN)的插入、删除与查找复杂度。文章详细介绍了构造函数、迭代器、容量接口、增删操作(如`insert`、`erase`)、查找统计(如`find`、`count`)及`multiset`特有的区间操作(如`lower_bound`、`upper_bound`、`equal_range`)。最后预告了`map`容器的学习,其作为键值对存储的关联式容器,同样基于红黑树,具有高效操作特性。
273 3
|
7月前
|
存储 算法 C++
【c++丨STL】priority_queue(优先级队列)的使用与模拟实现
本文介绍了STL中的容器适配器`priority_queue`(优先级队列)。`priority_queue`根据严格的弱排序标准设计,确保其第一个元素始终是最大元素。它底层使用堆结构实现,支持大堆和小堆,默认为大堆。常用操作包括构造函数、`empty`、`size`、`top`、`push`、`pop`和`swap`等。我们还模拟实现了`priority_queue`,通过仿函数控制堆的类型,并调用封装容器的接口实现功能。最后,感谢大家的支持与关注。
362 1
|
8月前
|
C++ 容器
【c++丨STL】stack和queue的使用及模拟实现
本文介绍了STL中的两个重要容器适配器:栈(stack)和队列(queue)。容器适配器是在已有容器基础上添加新特性或功能的结构,如栈基于顺序表或链表限制操作实现。文章详细讲解了stack和queue的主要成员函数(empty、size、top/front/back、push/pop、swap),并提供了使用示例和模拟实现代码。通过这些内容,读者可以更好地理解这两种数据结构的工作原理及其实现方法。最后,作者鼓励读者点赞支持。 总结:本文深入浅出地讲解了STL中stack和queue的使用方法及其模拟实现,帮助读者掌握这两种容器适配器的特性和应用场景。
182 21
|
7月前
|
存储 算法 C++
深入浅出 C++ STL:解锁高效编程的秘密武器
C++ 标准模板库(STL)是现代 C++ 的核心部分之一,为开发者提供了丰富的预定义数据结构和算法,极大地提升了编程效率和代码的可读性。理解和掌握 STL 对于 C++ 开发者来说至关重要。以下是对 STL 的详细介绍,涵盖其基础知识、发展历史、核心组件、重要性和学习方法。