[杂乱笔记]C++标准模板库(STL)的几个常见容器用法(set、vector、queue、stack、map、pair、priority_queue、string)

前言:

STL(Standard Template Library),中文名标准模板库,是一个高效的C++程序库,包含很多常用的基本数据结构和基本算法,为C++程序员们提供了一个可扩展的应用框架,高度体现了软件的可复用性。

STL有六大组件:容器(containers)、迭代器(iterators)、空间配置器(allocator)、配接器(adapters)、算法(algorithms)、仿函数(functors)。其中主要的是容器(用来管理某类对象的集合)、迭代器(用来在一个对象集合的元素上进行遍历操作)、算法(用来处理对象集合中的元素)三部分。

STL的基本观念就是将数据(数据由容器进行管理)和操作分离(由算法进行)。而迭代器在两者间充当粘合剂,是任何算法都可以和任何容器交互运作。

以下我只介绍了编程中常用到的容器。参考了资料,希望对大家有帮助,如果有错的地方,多多指点!!!

一、vector的常见用法详解

vector翻译为向量,一般叫变长数组,也就是长度根据需要而自动改变的数组。
1、vector的定义:vector<typename> name

(1)如果typename为整型、字符型、浮点型;

vector<int>name;
vector<double>name;
vector<char>name;

(2)如果typename为结构类型;

vector<node>name;

(3)如果typename为容器(vector、map、set...),定义的时候一定要在>>符号之间加上空格,因为一些使用c++11之前标准的编译器会把它视为移位操作,导致编译错误。

vector<vector<int> >name;

(4)数组a[]中的每一个元素都是一个vector

vector<typename>a[size];

2、vector容器内元素的访问

(1)通过下标访问,如vector<int>a,a[0]....a[a.size()-1].

(2)迭代器(iterator)访问,可以理解为一种类似指针的东西

vector<typename>::iterator it;

这样就得到了迭代器it,且可以通过*it来访问vector里的元素。

vector<int>a;
a.push_back(8);
a.push_back(8);
a.push_back(5);
a.push_back(2);
a.push_back(0);
vector<int>::iterator it=a.begin();///a.begin()为取首元素地址,而it指向这个地址
for(int i=0;i<a.size();i++)
     printf("%d ",*(it+i));///等价于a[i]

///vector迭代器不支持it<a.end()写法
for(vector<int>::iterator it=a.begin();it!=a.end();it++)
        printf("%d ",*it);

在常用STL容器中,只有vector和string允许使用a.begin()+i的写法。普及地,a.end()是尾元素地址地下一个元素。

3、vector常用函数实例解释

vector<int>a;
    ///push_back()在vector后面添加一个元素
    a.push_back(8);
    a.push_back(8);
    a.push_back(5);
    a.push_back(2);
    a.push_back(0);
    a.push_back(1);

    ///删除vector尾元素
    a.pop_back();

    int n=a.size();///获取vector元素个数
    a.clear();///清空vector中的所有元素
    
    a.insert(a.begin()+2,1);///将1插入到a[2]位置
    
    a.erase(a.begin()+2);///删除a[2]这个元素
    a.erase(first,last);///删除区间[first,last)内的所有元素

4、vector的常见用途

(1)储存数据

①vector可以作为数组使用,而且在一些元素个数不确定的场合可以很好地节省空间。

②有些场合需要根据一些条件把部分数据输出在同一行,数据中间用空格隔开。由于输出数据地个数是不确定地,为了更方便地处理最后一个满足条件地数据后面不输出额外地空格,可以先用vector记录所有需要输出地数据,最后一次性输出。

(2)用邻接表存储图

使用邻接表可以让一些对指针不太熟悉地读者有一个比较方便地写法。

二、set的常见用法详解

set翻译为集合,是一个内部自动有序且不含重复元素的容器。set的头文件为#include<set>,set内元素自动递增排序,且自动去除了重复元素。

1、set的定义写法和vector基本一致,typename可以为int、char、double、结构体、STL容器。

 set<int>name;
 set<double>name;
 set<char>name;
 set<node>name;
 set<vector<int> >name;
 set<int>a[size];

2、set容器内元素的访问:只能通过迭代器iterator访问。

  set<int>a;
  a.insert(8);
  a.insert(8);
  a.insert(5);
  a.insert(2);
  a.insert(0);
  for(set<int>::iterator it=a.begin();it!=a.end();it++)
     printf("%d",*it);

由于除了vector和string之外的STL容器都不支持*(it+i)的访问方式,通过*it来访问set里的元素。

3、set常见函数实例解析

set<int>a;
  a.insert(8);///把8插入set容器中,自动去重和递增排序
  a.insert(5);
  a.insert(2);
  
  set<int>::iterator it = a.find(2);///在set中查找2,返回对应值为2的迭代器
  printf("%d",*it);///2
  a.erase(it);///it为所要删除元素的迭代器
  a.erase(it,a.end());///删除区间之间的信息
  int n = a.size();///返回容器的个数
  a.clear();///清空set容器的所有元素

4、set的常见用途

(1)set最重要的作用就是去重并按升序排序,因此喷到需要去重但却不方便直接开数组的情况。

(2)set中的元素是唯一的,如果需要处理不唯一情况,则需要使用multiset。

三、string常见用法详解

1、string的定义:string str;其也可以初始化。

2、string中的内容的访问

(1)通过下标访问:

string str="abcd";
  for(int i=0;i<str.length;i++)
    printf("%c",str[i]);
printf("%s\n",str.c_str());

(2)通过迭代器访问

  string str="abcd";
  string::iterator it;///string不像其他STL容器那样需要参数
  for(string::iterator it = str.begin();it!=str.end();it++)
    printf("%c",*it);    
  ///string也可以和vector一样直接对迭代器加减某个数字

3、string常用函数实例解析

(1)string的加法

string str1="abc";
string str2="xyz";
string str;
str=str1+str2;///赋值于str
str1+=str2;///str2拼接在str1后

(2)string的比较

string str1="a";
string str2="aa";
string str3="abc";
string str4="xyz";
if(str1<str2)  ...;///如果字典序str1<str2
if(str1!=str2) ...;///如果str1!=str2
if(str4>=str3) ...;///如果字典序str4>=str3

(3)length()或size()(容器元素的个数)、clear()(清空容器)。

(4)insert()(它有很多种写法),下面介绍常用的:

string str="abcxyz";
string str1="bao";
str.insert(3,str1);///在str[3]插入字符串str1
str.insert(it,first,last);///it插入[first,last)区间的子字符串

(5)erase(),与之前的容器的差不多。就是多了一个删除区间元素的方法

str.erase();///删除单个元素
str.erase(first,last);///删除区间[first,last)内的元素
str.erase(pos,length);///删除从起始位置pos的length个元素

(6)string::npos

string::npos用以作为find函数失配时的返回值,是一个常数,本身的值为-1或4294967295(unsigned_int最大值)

(7)substr(pos,len)、find()、replace()

string str="Hello World!";
str1=" ";
str.substr(3,5)///str.substr(pos,len)从pos开始、长度为len的子串

str.find(str1);///返回str出现子串str1第一次出现的位置。如果str1不是str子串,那么就返回string::npos
str.find(str2,pos);///从str固定位置pos开始匹配,返回值与上面一样

str2="Hi!";
str.replace(pos,len,str2);///从str位置pos开始、长度为len的子串替换str2
str.replace(it1,it2,str2);///用str的迭代器[it1,it2)范围内的子串替换str2

四、map的常见用法详解

map翻译为映射,也是常用的STL容器。在定义数组时,其实(如int a[10];)就是定义了从int型到int型的映射,比如a[3]=10;(从3映射到10),比如一个字典,提供了很多字符串和页码(字符串-->页码),如果用数组来定义会显得不方便。这时就考虑map吧,选择它没错,map可以将任何基本类型(包括STL容器)映射到任何基本类型(包括STL容器)

1、map的定义

map<typename1,typename2> mp;///<>内填写两个类型,其中第一个是映射前的类型typename1,一个是映射后的类型typename2

注意:如果字符串到整型的映射,必须是string而不能用char数组。(map<string,int>mp或map<set<int>,string>

2、map容器内元素的访问

(1)下标访问:map中的键是唯一的,比如map<char,int>mp,mp['c']=20。

(2)通过迭代器访问:map的迭代器的定义和其他容器的定义都是一样的,但是其迭代器的使用方式与其他STL容器的不同。使用it->first访问键,使用it->second访问键。

map<char,int> mp;
mp['m']=20;
mp['n']=30;

for(map<char,int>::iterator it = mp.begin();it!=mp.end();it++)
printf(%d %d\n,it->first,it->second);

3、map常见函数实例解析

map<char,int> mp;
mp['m']=20;
mp['n']=30;

mp.find(key);///返回键为key的映射的迭代器

map<char,int>::iterator it = mp.find('m');
mp.erase(it);///删除m
mp.erase(first,last);///删除区间[first,last);

int len = mp.size();///获取容器内的个数
mp.clear();///清空容器

4、map的容器常见用途

(1)需要建立字符或字符串与整数之间映射的题目,使用map可以减少代码量

(2)判断大整数或其他类型数据是否存在的题目,可以把map当bool数组用。

(3)字符串和字符串的映射也有可能会遇到。

map的键和值是唯一的,如果一个键需要对应多个值,就只能用multimap。

五、queue的常见用法详解

queue翻译为队列,在STL中主要则是实现了一个先进先出的容器。

1、queue的定义:queue<typename> name;

2、queue容器内元素的访问(只能通过front()来访问队首元素,或是通过back()来访问队尾元素)

3、queue常用函数实例解析

queue<int>q;

q.push(1);
q.push(3);
q.push(2);///2入队
printf(%d %d %d\n,q.front(),q.back(),q.size());///可以分别获得队首元素和队尾元素,获取队列内元素个数

q.pop();///队首元素出队
if(!q.empty()) ...;///检测队列是否为空

注意:使用front()和pop()函数前,必须用empty()判断队列是否为空。

4、queue的常见用途

(1)方便实现广度优先搜索

(2)STL的容器中还有两种容器跟队列有关,分别是双端队列deque和优先队列priority_queue,前者是首尾皆可插入和删除的队列,后者是使用堆实现的默认将当前队列最大元素置于队首的容器。

六、priority_queue的常见用法详解

priority_queue又称为优先队列,其底层用堆来实现的,在优先队列中,队首元素一定是当前队列中优先级最高的那一个。

1、priority_queue的定义:priority_queue<typename>name;

2、priority_queue容器内元素的访问

和队列不同,priority_queue只能通过top()函数来访问队首元素(也可以称为堆顶元素),也就是优先级别最高的元素。

3、priority_queue常用函数实例解析

priority_queue<int>q;

q.push(1);
q.push(3);
q.push(2);///2入队
printf(%d %d\n,q.top(),q.size());///可以分别获得队首元素,获取队列内元素个数

q.pop();///队首元素出队
if(!q.empty()) ...;///检测队列是否为空<int>q;

4、priority_queue内元素优先级的设置

(1)基本数据类型的优先级设置

基本数据类型就是int型、double型、char型等可以直接使用的数据类型,优先队列对他们优先级设置一般是数字大的优先级越高

priority_queue<int,vector<int>,less<int> >q;///等价priority_queue<int>q
q.push(2);
q.push(3);
q.push(1);
printf("%d\n",q.top());///输出3

vector<int>来自承载底层数据结构堆的容器,less<int>表示数字越大的优先级越大,greater<int>表示优先级别越小。

(2)结构体的优先级设置

struct fruit{
   string name;
   int price;
   friend bool operator < (fruit f1,fruit f2){///重载,不能是大于号,否则会编译出错
     return f1.price < f2.price;///价格高的水果优先级高(从低到高),否则>就是价格低的水果优先级低(从高到低)
  }
  ///如果结构内的数据比较庞大,可以在参数使用引用,const fruit f1、const fruit f2
}

friend这个是友元,是减少系统开销,提高效率的。注意:优先队列的这个函数与sort中的cmp效果相反。

5、priority_queue的常见用途

(1)贪心问题

(2)Dijkstra算法进行优化

七、stack的常见用法详解

stack翻译为栈,是STL中实现的先进先出的容器。

1、stack常见函数实例

stack<int>st;
st.push(1);
st.push(3);
st.push(2);///入栈
int x=st.top();///取栈顶元素
st.pop();///删除栈顶元素

int n = st.size();
if(!st.empty()) ....;///判断栈是否为空

2、stack的常见用途

用来模拟实现一些递归,防止程序对栈内存的限制,而导致程序运行出错

八、pair的常见用法详解

pair是一个非常实用容器,当想要将两个元素绑在一起作为一个合成元素、又不想因此定义结构体,使用pair可以很方便地作为一个代替品,pair实际上可以看作一个内部有两个元素地结构体,且两个元素地类型是可以指定的。(头文件utility,map头文件会自动添加utility头文件)

struct pair{
    typename1 first;
    typename2 second;
}

1、pair的定义

pair有两个参数,分别对应first和second的数据类型,它们可以是任意基本数据类型或容器。

2、pair中元素的访问

pair中只有两个元素,分别是first和second,只需要按正常结构体的方式去访问即可。

///pair<typename1,typename2>name;
pair<string,int>p;
p.first="Hello";
p.second=3;///初始化

pair<string,int>p("Hello",3);///初始化

///临时构建一个pair
p=pair<string,int>("Hello",3);
p=make_pair("Hello",3);///使用自带函数

3、pair常用函数实例解析

比较操作数:比较规则(==,!=,<,<=,>,>=)先以first的大小为标准,只有当first相等才去判断second的大小。

pair<int,int>x(1,2);
pair<int,int>y(1,1);
pair<int,int>z(2,3);

if(x>y) ....;///first相等,比较second
if(y<z) ....;///比较first

4、pair的常见用途

(1)是来代替二元结构体及其函数,可以节省编码时间。

(2)作为map键值对来进行插入。

map<string,int>mp;
mp.insert(make_pair("Hello",3));
mp.insert(pair<string,int>("Hi",5));

for(map<string,int>::iterator it=mp.begin();it!=mp.end();it++)
       cout<<it->first<<" "<<it->second<<endl;

九、参考资料

1、https://blog.csdn.net/TeFuirnever/article/details/104438908?utm_source=app(【C++100问】深度总结STL基本容器的使用)

2、《算法笔记》

  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: C++ 标准模板STL)是一个强大的工具,为程序员提供了许多可以直接使用的容器、算法和迭代器。《C++ 标准模板编程实战》这本书集中讲解了 STL 的使用方法和实战技巧,旨在帮助读者开发出高效且易于维护的 C++ 程序。 这本书共分为四个部分。第一部分介绍了 STL 的基础知识,主要包括容器、迭代器、算法、函数对象等内容。第二部分重点讲解了序列容器和关联容器,以及它们常见的应用。第三部分主要是算法,详细介绍了 STL 中常用的算法,并且通过实例演示了其使用方法。第四部分主要是 STL 的高级应用,如智能指针、异常处理、多线程等。 此外,这本书还提供了大量的实战案例,这些案例既包括独立的小应用程序,也包括较为完整的项目代码。通过这些案例,读者可以深入了解 STL 的使用和设计思路,并掌握一些实用的编程技巧。 总的来说,这本《C++ 标准模板编程实战》是一本非常实用的书籍,不仅适合初学者入门,也适合有一定经验的开发者进一步提高自己的编程技能。建议读者在学习这本书时,可以边读边动手实践,更好地理解和掌握其中的内容。 ### 回答2: c++标准模板编程实战是一本非常经典、详实的c++ STL实战教材,主要讲解了STL的各种容器、算法和迭代器的常用操作和实现原理,并且通过大量的实例演示了STL在真实项目中的实际应用。 本书总共分为10个章节,前两章是介绍STL的基础知识和核心组件,包括迭代器、容器、算法等;第三章是介绍序列容器,主要包括vector、list、deque、stackqueue、heap、priority_queue和bitset等;第四章是介绍关联容器,主要包括set、multisetmap、multimap等;第五章是介绍迭代器,包括迭代器分类,迭代器实现方式和应用场景等;第六章是介绍函数对象,包括函数对象的定义、STL内置函数对象、自定义函数对象和函数对象适配器等;第七章是介绍算法基础,包括常用算法和自定义算法的实现;第八章是介绍字符串,在字符串操作方面,STL提供了string和wstring类,以及一些与之相关的算法;第九章是介绍STL的高级用法,包括元编程、策略模式、继承体系、嵌套类和allocator等;第十章是介绍STL和相关技术的未来发展趋势和发展方向。 总的来说,c++标准模板编程实战是一本非常好的STL实战教材,既可以作为初学者入门的指南,也可以作为中高级程序员巩固和深入学习STL的参考书。无论是学习STL的基础知识、习惯性使用STL容器和算法,还是在项目中灵活高效地应用STL,都会受益匪浅。 ### 回答3: c标准模板STL)是一组C++模板类和函数的集合,可以让程序员使用一些高效的算法和数据结构,从而降低了开发者的工作量,提高了C++程序的效率和可维护性。 《C++标准模板编程实战》是一本介绍STL的经典教材,全书共分为25个章节,内容涉及到STL的迭代器、算法、容器、函数对象、适配器等方面。可谓是STL入门的重要读物。 该书的编写思路以工程实践为导向,讲解一些常用的数据结构和算法的实现过程,并给出了一些标准中经典的函数的代码实现。例如,生成随机数的代码、字符串排序的代码、实现二叉的代码等等。这些代码可以帮助开发者更好地理解STL中的模板类和函数的实现原理和效率。 此外,该书对STL的算法进行了详细介绍,包括容器、迭代器、函数对象等方面的应用。为了方便程序员,书中还提供了一些实用的STL程序的代码,例如STL的多个容器和关联式容器,还有STL中提供的适配器等。 总之,《C++标准模板编程实战》是学习STL的必备参考书,不仅深入浅出地讲解了STL的实现原理和应用,更是教会了我们如何将STL运用到工程中,将编程变得更加高效和简单。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值