首页 > 编程语言 >C++ STL

C++ STL

时间:2022-10-29 23:02:02浏览次数:60  
标签:容器 string STL 元素 C++ str 字符串 size

概述

STL主要有container , algorithm和iterator三大部分构成

  • 容器用于存放数据对象
  • 算法用于操作容器中的数据对象
  • 迭代器是算法和容器之间的中介

STL容器

STL容器是一种数据结构,例如链表、栈和队列等

STL常用数据结构和头文件:

数据结构

说明

头文件

向量vector

连续存放数据,底层为数组,支持快速随机访问

<vector>

字符串string

字符串

<string>

双端队列deque

连续存储的指向不同元素的指针所组成的数组。支持首尾元素快速删除,也支持随机访问

<deque>

链表list

由节点组成的链表,每个节点包含着一个元素。底层结构为双向链表,支持结点的快速删除。

<list>

栈stack

先进后出

<stack>

队列queue

先进先出

<queue>

优先队列priority_queue

元素的进出队顺序由关系函数决定。底层结构一般为vector或者deque

<queue>

集合set/ 多重集合multiset

结点组成的红黑树,每个节点包含一个元素,set中的所有元素有序但是不重复,multiset中的所有关键字有序但是可以重复

<set>

映射map/多重映射multimap

由键值对组成的集合,底层数据结构为红黑树,map中的所有关键字有序但是不重复,multimap中的所有关键字有序但是可以重复

<map>

使用STL需要引入命名空间: std

STL算法

STL算法是用来操作容器中数据的模板函数,大概提供了100个实现算法的模板函数。

使用泛型设计,STL算法有很好的通用性

STL算法主要由头文件<algorithm>、<numeric> 和<functional>组成

  • <algorithm>是所有STL头文件中最大的一个,由一大堆模板函数组成,涉及容器元素的比较,排序,查找,遍历,复制,删除,修改等等
  • <numeric> 体积很小,只包含几个简单的数学运算的模板函数
  • <functional>中定义了一些模板类,用于声明关系函数对象

STL迭代器

STL迭代器用于访问容器中的数据对象。

每个容器都有自己的迭代器,只有容器自己知道如何访问自己的元素。算法通过迭代器来定位和操作容器中的元素

迭代器操作符:

  • ++ 递增迭代器,访问下一个数据对象
  • -- 递减迭代器
  • *返回迭代器所指的元素值

常用迭代器

  • iterator
    指向容器中存放元素的迭代器,用于正向遍历容器中的元素
  • const_iterator
    指向容器中存放元素的常量迭代器,只能读取元素
  • reverse_iterator
    指向容器中存放元素的反向迭代器,反向遍历元素
  • const_revserse_iterator
    指向容器中存放元素的常量反向迭代器,只能读取元素

常用的STL容器

每一个容器都是一个类模板

大致分类为顺序容器、关联容器、适配器容器

  • 顺序容器
    按照线性次序的位置存储数据,有: vector, string, deque, list
  • 关联容器
    每一个元素有一个key,通过key 来存储和读取元素,与元素在容器中的位置无关,所以关联容器不提供front(), push_front() ,back()...
  • 适配器容器
    基于其他容器实现的容器,适配器容器包含另一个容器作为其底层容器,在底层容器的基础上实现适配器容器的功能。
vector向量容器

相当于数组,存储具有相同数据类型的一组元素。

可以随机访问元素,但是插入、删除元素较慢。

可以动态增加大小 --> 通常按照两倍大小扩展

定义
vector<int> v1;
vector<int> v2(10); // 初始大小为10
vector<int> v3(10,1); // 初始大小为10,每个元素的初始值为1
vector<int> v4(a,a+5); // 用数组a[0..4] 共5个元素初始化v4
成员函数
  • empty() 判断是否为空
  • size() 实际元素的个数
  • [] 返回指定下标的元素
  • reserve(n) 为当前vector预分配n个元素的存储控件
  • capacity() 返回容量
  • resize(n) 调整大小
  • push_back() 向尾部添加一个元素
  • insert(pos,elem) 在pos位置添加一个元素
  • front() 获取第一个元素
  • back() 获取最后一个元素
  • erase() 删除某个迭代器或者迭代器区间指定的元素
  • clear() 清空
  • begin() 引用容器的第一个元素
  • end() 引用容器的最后一个元素后面的位置
  • rbegin() 引用容器的最后一个元素
  • rend() 返回容器第一个元素前面的一个位置
string 字符串容器

保存字符序列的容器,所有元素为字符类型, 类似vector<char>

定义
string(); // 建立一个空的字符串
string(const string & str) ; // 用字符串str建立当前的字符串
string(const string & str,size_type str_idx); // 用字符串str起始于str_idx的字符建立当前字符串
string(const string & str,size_type str_idx,size_type str_num); // 用字符串str起始于str_idx 的str_num 个字符建立当前字符串
string(const char * cstr); // 用c字符串cstr建立当前字符串
string(const char * cstr,size_type chars_len); // 用c字符串cstr开头的chars_len 个字符建立当前字符串
string(size_type num,char c); // 用num个字符c建立当前字符串
成员函数
  • empty()
  • size()
  • length()
  • [idx] 返回索引idx位置上的字符
  • at(idx)
  • compare(const string& str) 返回比较结果,相等返回0
  • append(str) 在字符串的末尾添加一个字符串str
  • insert(size_type idx,const string & str) 在当前字符串idx处插入一个字符串str
  • find(string & s, size_type pos) 从pos位置开始查找字符串s的第一个位置,没有返回-1
  • replace(size_type idx,size_type len,const string & str) 将字符串起始于idx的len个字符用一个字符串str替换
  • replace(iterator beg,iterator end,const string& str) 将当前字符串中有迭代器beg和end指向区间的所有字符用一个字符串str替换
  • substr(size_type idx) 返回当前字符串起始于idx的子串
  • substr(size_type idx,size_type len) 返回当前字符串起始于idx的长度为len 的子串
  • clear()
  • erase() 删除所有字符串
  • erase(size_type idx) 删除从idx开始的所有字符
  • erase(size_type idx,size_type len) 删除从下标idx开始的len个字符
deque双端队列

块内连续,块间不连续

定义
deque<int> dq;
deque<int> dq(10);
deque<int> dq(10,1); // 10个元素,每个元素的初值都是1
deque<int> dq(dq1.begin(),dq1.end()) // 使用dq1的元素初始化dq
成员函数
  • empty()
  • size()
  • push_front(elem)
  • push_back(elem)'
  • pop_front()
  • pop_back()
  • erase()
  • clear()
  • begin()
  • end()
  • rbegin()
  • rend()
list链表容器
定义
list<int> l1;
list<int> l2(10);
list<int> l3(10,1);
list<int> l4(a,a+5); // 使用数组a[0..4] 共5个元素初始化l4
成员函数
  • empty()
  • size()
  • push_back()
  • pop_back()
  • remove() 删除链表容器中所有指定值的元素
  • remove_if(cmp) 删除链表容器中满足条件的元素
  • erase()
  • unique() 删除链表容器中相邻的重复元素
  • clear()
  • insert(pos,elem)
  • insert(pos,n,elem) 在pos位置插入n个elem
  • insert(pos,pos1,pos2) 在迭代器pos处插入[pos1,pos2)的元素
  • reverse() 反转链表
  • sort() 排序
  • begin()
  • end
  • rbegin()
  • rend()

STL提供的sort() 算法主要用于支持随机访问的容器,list容器不支持随机访问,为此list容器提供了sort() 成员函数用于元素排序

set 集合/ multiset多重集合容器
  • set中的关键字是唯一的
    在插入元素时,如果已经存在则不插入
  • multiset 中的关键字可以不唯一
    允许存在相同关键字的元素,删除时会将相同关键字的元素都删除,并返回删除个数

默认情况下会对元素按照关键字自动进行升序排列,同时支持交,差,并等集合运算

成员函数
  • empty()
  • size()
  • insert()
  • erase()
  • clear()
  • count(k) 返回容器中关键字k出现额次数
  • find(k) 如果存在关键字k的元素,返回该元素的迭代器,否则返回end()值
  • upper_bound() 返回一个迭代器,指向关键字大于k的第一个元素
  • lower_bound()
  • begin()
  • end()
  • rbegin()
  • rend()
map映射/multimap多重映射容器

实现关键字与值映射,可以使用一个关键字key来访问响应的数据值

map/multimap中的key和value是一个pair类结构

struct pair{
T first;
T second;
}

map/multimap 可以根据key快速找到与之对应的value( 时间复杂度 O(log2(n)) )

  • map中不允许key重复,支持[]运算符
  • multimap允许key重复, 但是不支持[] 运算符
成员函数
  • empty()
  • size()
  • map[key] 返回关键字为key的元素的引用,如果不存在这样的关键字,则以key作为关键字插入一个元素( 不适合multimap )
  • insert(elem) 插入一个元素并返回该元素的位置
  • clear()
  • find()
  • count() 容器中指定关键字的元素个数,map中只有1 和 0
  • begin()
  • end()
  • rbegin()
  • rend()
map<char,int> mymap;
mymap['a'] = 1;
stack 栈容器

后进先出

默认底层是deque容器,也可以指定底层容器

// 指定底层容器为vector, 第二个参数指定底层容器
stack<string,vector<string>> myst;

stack容器只有一个出口-->栈顶,可以在栈顶插入,删除元素,不允许顺序遍历

成员函数
  • empty()
  • size()
  • push(elem)
  • top() 返回栈顶元素
  • pop()
queue队列容器

先进先出

不允许顺序遍历

成员函数
  • empty()
  • size()
  • front() 返回队头元素
  • back() 返回队尾元素
  • push(elem) 入队
  • pop() 出队
priority_queue优先队列容器

优先队列中元素,出队将按照优先级的高低。

成员函数
  • empty()
  • size()
  • push(elem) 元素进队
  • top() 获取队头元素
  • pop() 出队

优先队列中优先级的高低由队列中数据元素的关系函数(比较运算符) 确定

  • 默认的关系函数-> 对于内置数据类型,默认关系函数是值越大优先级越高 --> 大根堆
  • 可以重载自定义关系函数
//1. 重载“<”操作符来定义优先级
//定义结构体
struct info{
string name;
float score;
//重载< 操作符,指定优先级规则(排序规则)
bool operator < (const info & a)const{
//按从小到大排序(原本是< ,现在的功能是>)
return score > a.score;
}
};

// priority_queue<info> pq;
//2. 重载“()”操作符来定义优先级
/重载()
struct myComp{
bool operator () (const int &a,const int& b){
//由小到大
return a>b;
}
};
//定义优先队列,显式说明内部结构是vector
//priority_queue<int,vector<int>,myComp> pq;

STL的使用

stack的使用

判断一个含有(), [],{} 3中类型的表达式中所有的括号是否匹配

分析:所有的右括号都是和前面最近的左括号匹配

#include <iostream>
#include <stack>
using namespace std;
// 判断str中的括号是否匹配
bool solve(string str){
stack<char> st;
int i = 0;
while(i < str.length()){
if(str[i] == '(' || str[i] == '{' || str[i] == '['){
st.push(str[i]);
}else if(str[i] == ')'){
if(st.top() != '('){
return false;
}else{
st.pop();
}
}else if(str[i] == '}'){
if(st.top()!='{'){
return false;
}else{
st.pop();
}
}else if(str[i] == ']'){
if(st.top()!='['){
return false;
}else{
st.pop();
}
}
i++;
}

if(st.empty()){
return true;
}else{
return false;
}
}
排序

对于list 容器中的元素可以使用成员函数sort()

对于数组或者vector等具有随机访问特定的容器可以使用STL算法sort()

内置数据类型排序

sort() 默认以less<T>小于关系函数作为关系函数实现递增排序。

为了实现递减排序需要调用<functional> 头文件中定义的greater类模板

// 递减排序
sort(myv.begin(),myv.end(),greater<int>());

less<T> ,greater<T> 均属于STL关系函数对象,分别支持对象之间的小于,大于比较,返回布尔值。

包含在functional头文件中

自定义数据类型排序
  • 重载 < 运算符,以实现按指定成员的递增或者递减排序
// 递增
bool operator <(const Stud& s) const {
return no<s.no;
}
  • 自定义关系函数,实现按照指定成员的递增或者递减排序

重载() 运算符

struct Cmp{
bool operator()(const Stud &s,const Stud&t) const{
return s.no < t.no;
}
}

sort(myv.begin(),myv.end(),Cmp()); // 使用Cmp中的()运算符进行排序

可以采用STL的优先队列来实现堆

优先队列的优先级高低由队列中数据元素的关系函数确定 --> 确定关系

内置数据类型

默认使用less<T> 作为关系函数,值越大优先级越高

可以改为greater<T> 作为关系函数

自定义类型
  1. 在声明的结构体类型中重载<运算符,指定优先级
  2. 在声明结构体中重载 > 运算符,此时需要指定优先级队列的底层容器和greater<T>
  3. 自定义关系函数,需要重载() 运算符,也需要指定底层容器。

标签:容器,string,STL,元素,C++,str,字符串,size
From: https://blog.51cto.com/u_14926062/5806590

相关文章

  • Modf is not a member of std in C++
    ModfisnotamemberofstdinC++ 2minuteread OnthispageIntroductionPotentialcausesFix#1:AddiostreamtoyourdepedenciesFix#2:Usingnamesp......
  • python 与C++ 利用socket实现json数据传输
    单机python与C++程序利用socket实现json数据传输目录单机python与C++程序利用socket实现json数据传输需求实现方法的选择具体实现流程图示涉及到的技术1socket......
  • C++ 实现argosort
    #include<bits/stdc++.h>usingnamespacestd;intmain(){intn=5,t;vector<int>a,b;for(inti=0;i<n;++i){scanf("%d",&t......
  • C++多继承下,派生类对象有几张虚函数表?
    #include<iostream>#include<string>#include<typeinfo>usingnamespacestd;//基类classBase1{public:Base1():x(1){}virtualvoidplay(){cout<<"Base1::p......
  • C/C++ 交换机管理命令实战
    #include<stdio.h>#include<string.h>#include<stdlib.h>#include<iostream>#include<conio.h>usingnamespacestd;structport{charname[16];i......
  • C++ primer 7.2 7.3笔记
    7.2访问控制与封装访问说明符:public,privateclass和struct的区别:默认访问权限不一样,class默认所有成员是private,struct默认所有成员是public。7.2.1友元类可以允许......
  • C++20 实现字符串类型的转换操作
    文章目录​​1、C语言库​​​​1.1printf/scanf(Clibrary)​​​​1.2floor/ceil/round(Clibrary)​​​​1.3itoa/atoi(Clibrary)​​​​1.4sprintf(Clibrary)......
  • c++17 注解标签 attributes & c++ 枚举值
    c++标注c++17后逐渐完善注解标签语法:[[attribute]]types/functions/enums/etc 告诉编译器没有返回值[[noreturn]]常用于系统函数设计,如std::abort()std::exit()......
  • C++创建桌面应用程序:处理对话框DialogBox
    VS2019新建C++桌面向导://Project1.cpp:定义应用程序的入口点。//#include"framework.h"#include"Project1.h"INT_PTRDlgproc(HWNDhwndDlg,UINTuMsg,WPARAMwParam......
  • C/C++ struct结构体的三种使用方法
    #include<stdio.h>#include<string.h>#include<stdlib.h>#include<iostream>#include<conio.h>usingnamespacestd;structhero{charname[16];ch......