C++中常用到的容器
这里主要讲C++中经常用到的一些保存数据的容器,其中也会介绍string。
在C++11中提到了很多容器,这里主要介绍:vector、list、map。还有一些其他的容器就不做介绍了。
1.String
这是我们用得最多的用来表示字符串的类型了 ,下面介绍一下String的一些知识:
初始化:
string s1;//这里默认初始化,s1是一个空字符串
string s2 = s1;//s2是s1的副本,此时s2和s1是里面保存的是一样的内容
string s3 = "hiya";//s3是该字符串字面值的副本
string s3("hiya");//等价于上面的s3
string s4(10, 'c');//s4的内容是cccccccccc。(10个c)
string对象上的操作
os<<s; 将s写到输出流os当中,返回os
is>>s; 从is中读取字符串赋给s,字符串以空白分隔,返回is
getline(is, s) 从is中读取一行赋给s,返回is
s.empty(); s为空返回true,否则返回false
s.size(); 返回s中字符的个数
s[n]; 返回s中第n个字符的引用,位置从0计起
s1 + s2; 返回s1和s2连接后的结果
s1 = s2; 用s2的副本代替s1中原来的字符;
s1 == s2; 如果s1和s2中所含字符完全一样,,则它们相等;string对象的相等性判断对字母的大小写敏感
s1 != s2;
<,<=,>,>= 利用字符在字典中的顺序进行比较,且对字母的大小写敏感
这里对于string类型的数据,我们可以像访问数组元素一样访问string中的对应字符。
注:还可以使用迭代器来对字符串类型做一些操作,如
string s("some things");
if (s.begin() != s.end())
{
auto it = s.begin; //it表示s的第一个字符
*it = touper(*it); //将当前字符改为大写形式
}
2.vector
vector类型得到标准定义为:vector<T> v1;其中T为类型,这里可以是内置类型,如int等,也可以是结构体或者类类型。
初始化
vector<T> v1; //v1是一个空的vector,它潜在的元素是T类型,执行默认初始化
vector<T> v2(v1); //v2中包含有v1的所有元素的副本
vector<T> v2 = v1; //等价于v2(v1),v2中包含有v1所有元素的副本
vector<T> v3(n, val); //v3包含了n个重复的元素,每个元素的值都是val
vector<T> v4(n); //v4中包含了n个重复执行了值初始化的对象
vector<T> v5{a,b,c,......}; //v5包含了初始值个数的元素,每个元素被赋予了相应的初始值
vector<T> v5 = {a,b,c,.......}; //等价于上面的v5
这里要区分是列表初始化还是值初始化
vector<int> v1(10); //v1有10个元素,每个元素的值都是0
vector<int> v2{10}; //v2有1个元素,该元素的值为10
vector<int> v3(10,1); //v3有10个元素,每个元素的值都是1
vector<int> v4{10,1}; //v4有2个元素,值分别为10和1
其他操作
v.empty() 如果v不返回任何元素,返回真,否则返回假
v.size() 返回v中元素的个数
v.push_back(t) 向v的尾端添加一个值为t的元素
v[n] 返回v中第n个位置上的元素的引用,从0开始计起
v1 = v2; 用v2中的元素的拷贝替换v1中的元素
v1 = {a,b,c,......} 用列表中的元素来拷贝替换v1中的元素
v1 == v2 v1和v2相等当且仅当它们的元素数量相同且对应位置的元素值都相同
v1 != v2
<,<=,>,>= 以字典的书序进行比较
上述介绍的string和vector我们都可以使用基于范围的for语句来进行范文,如:
string str("hello");
for(auto c : str)
cout << c << endl;
这里将依次输出str中的每一个字符,且每一个字符占一行
vector<string> vec{"hello", “world"};
for(auto c : vec)
cout << c << endl;
这里会输出hello和world,且每个单词占一行
对于vector我们还可以通过基于范围的for语句来改变当中的没一个元素的值
vector<int> v{1,2,3,4,5,6,7,8,9};
for(auto &i : v) //对于v中的每一个元素(注意:i是一个引用)
i *= i; //求每个元素的平方值
for(auto i : v)
cout << i << " ";
cout << endl;
输出结果为:1 4 9 16 25 36 49 64 81
注:不能使用下标的形式往vector对象中添加元素
3.list
这里list和vector基本操作相同,这里就说说它们之间的区别,便于我们选择用哪一种容器更好,区别如下:
(1) vector是顺序表,表示的是一块连续的内存,元素被顺序存储;list是双向连接表,在内存中不一定连续。
(2)当数值内存不够时,vector会重新申请一块足够大的连续内存,把原来的数据拷贝到新的内存里面;list因为不用考虑内存的连续,因此新增开销比vector小。
(3)list只能通过指针访问元素,随机访问元素的效率特别低,在需要频繁随机存取元素时,使用vector更加合适。
(4)当向vector插入或者删除一个元素时,需要复制移动待插入元素右边的所有元素;因此在有频繁插入删除操作时,使用list更加合适。
下面介绍一个list和vector中的插入。
vector中可以使用push_back()向容易的尾端插入指定的数据,但是不能使用push_front,该函数是向容器的首端插入指定的元素,这里我们就可以使用insert()函数来实现插入操作,insert包括两个参数,一个参数是迭代器,用于指出插入元素的位置,这里即使是尾端迭代器也可以,所以insert完成的是向该迭代器所指位置的前一个位置插入指定的元素,如:
vector<string> vec;
list<string> lst;
lst.insert(lst.begin(), "Hello"); //向list类型容器的lst的首端插入”Hello“
vec.insert(vec.begin(), "Hello"); //同上
insert除了上述接收两个参数的形式外,还可以接收三个参数,如:
vec.insert(vec.begin(), 10, "Hello"); //添加10个Hello字符串到vec的首端
vector<string> v = {"quasi", "simba", "frollo", "scar"};
vec.insert(vec.begin(), v.end()-2, v.end()); //将v的最后两个插入vec的首端
lst.insert(lst.end(), {"shese", "words", "will", "go”, "at", "the", "end"}); //将后面的列表中的字符串插入lst的尾部
注:迭代器表示要拷贝的范围,不能指向与目的位置相同的容器,如:
lst.insert(lst.begin(), lst.begin(), lst.end());// 这里要插入的迭代器容器是lst,但是要拷贝的范围也是lst,所以运行时会出现错误。
4.map
map是属于关联容器这一类的,包括两个参数,第一个参数是关键字,第二个参数的该关键字对应的值。
对map的一个经典例子是单词计数器程序:
map<string, size_t> word_count; //string 到size_t的空map
string word;
while(cin >> word)
++word_count[word]; //提取word的计数器并将其加1
for(const auto &w : word_count) //使用基于范围的for语句依次访问map中的数据
cout << w.first << "occurs" << w.second << ((w.second > 1) ? "times" : "time") << endl;
一般很多时候,我们会将map和set连起来一起用,如下面的例子是改进的上面的单词计数器的例子,本例子中只统计不在exclude中的单词
map<string, size_t> word_count;
set<string> exclude = {"the", "But", "And", "At", "A", "An"};
string word;
while(cin >> word)
if (exclude.find(word) == exclude.end())
++word_count[word];
C++中常用到的容器的更多相关文章
- J2EE项目开发中常用到的公共方法
在项目IDCM中涉及到多种工单,包括有:服务器|网络设备上下架工单.服务器|网络设备重启工单.服务器光纤网线更换工单.网络设备撤线布线工单.服务器|网络设备替换工单.服务器|网络设备RMA工单.通用原 ...
- java中常用的工具类(三)
继续分享java中常用的一些工具类.前两篇的文章中有人评论使用Apache 的lang包和IO包,或者Google的Guava库.后续的我会加上的!谢谢支持IT江湖 一.连接数据库的综合类 ...
- SSH框架应用中常用Jar包用途介绍
struts2需要的几个jar包:1)xwork-core-2.1.62)struts2-core-2.1.83)ognl-2.7.34)freemarker-2.3.155)commons-io-1 ...
- spring注解开发中常用注解以及简单配置
一.spring注解开发中常用注解以及简单配置 1.为什么要用注解开发:spring的核心是Ioc容器和Aop,对于传统的Ioc编程来说我们需要在spring的配置文件中邪大量的bean来向sprin ...
- javascript中常用坐标属性offset、scroll、client
原文:javascript中常用坐标属性offset.scroll.client 今天在学习js的时候觉得这个问题比较容易搞混,所以自己画了一个简单的图,并且用js控制台里面输出测试了下,便于理解. ...
- 记录下项目中常用到的JavaScript/JQuery代码二(大量实例)
记录下项目中常用到的JavaScript/JQuery代码一(大量实例) 1.input输入框监听变化 <input type="text" style="widt ...
- Kubernetes 在生产环境中常用架构
Kubernetes 在生产环境中常用架构 首先,我们来梳理下Kubernetes生产架构,其设计适用于绝大多数环境.如下图所示 在该架构中,我们可以将其分为四层,如下: Client层:即Kuber ...
- 2019-2-20C#开发中常用加密解密方法解析
C#开发中常用加密解密方法解析 一.MD5加密算法 我想这是大家都常听过的算法,可能也用的比较多.那么什么是MD5算法呢?MD5全称是 message-digest algorithm 5[|ˈmes ...
- C++中常用的std标准容器
从c++11标准以来,c++中std定义的几种容器的效率非常高,优化的非常好,完全没有必要自己去定义类似的数据结构.了解使用它们,可以满足90%的日常编程需要.该篇文章基于c++11标准,从用户角度来 ...
随机推荐
- ELF 文件 动态连接 - 延迟绑定(PLT)
PLT 全称:Procedure Linkage Table ,直译:过程连接表 由于在动态连接中,程序的模块之间包含了大量的函数引用,所以在程序开始执行前,动态链接会耗费较多的时间用于模块之间函数引 ...
- asp.net core上使用Redis探索(2)
在<<asp.net core上使用Redis探索(1)>>中,我介绍了一个微软官方实现Microsoft.Extensions.Caching.Redis的类库,这次,我们使 ...
- Qt5中this application has requested the runtime to terminate it in an unusual way 无法运行问题的解决
在windows平台使用Qt5.8mingw版写出的程序,在Qt中运行正常,而以release的形式编译并且补充完必要的dll文件后,在其他电脑上运行出现了以下问题: 经过查阅许多资料和亲身实验,终于 ...
- Demo2
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...
- vue学习:props,scope,slot,ref,is,slot,sync等知识点
1.ref :为子组件指定一个索引 ID,给元素或者组件注册引用信息.refs是一个对象,包含所有的ref组件. <div id="parent"> <user- ...
- List,Set,Map三种接口的区别
set --其中的值不允许重复,无序的数据结构 list --其中的值允许重复,因为其为有序的数据结构 map--成对的数据结构,健值必须具有唯一性(键不能同,否则值替换) List按对象进 ...
- 关于Django升级的一些联想
刚刚阅读完django1.11的release note,从django1.4一直用到django1.11,以及即将到来的大版本django2.0,Django的版本升级策略和国内的技术现状对比称得上 ...
- __new__()方法的使用和实例化
Python中__new__()方法的使用和实例化 1 2 new()是在新式类中新出现的方法,它作用在构造方法init()建造实例之前,可以这么理解,在Python 中存在于类里面的构造方法init ...
- BOM和DOM的区别
一.BOM和DOM之间的关系图 window对象是BOM的顶层(核心)对象,所有对象都是通过它延伸出来的,也可以称为window的子对象由于window是顶层对象,因此调用它的子对象时可以不显示的指明 ...
- vue的生命周期钩子
生命周期过程: new vue() :vue实例进行初始化,读取所有生命周期函数,并没有执行(不会调用) beforeCreate():创建前,读取属性,计算属性,添加set/get,读取watch ...