C++ STL简述

目录
一、STL 1
二、string字符串 3
三、vector 5


一、STL

1.STL简介

STL的代码分三类:algorithm(算法)、container(容器)和iterator(迭代器),几乎所有的代码都采用了模板类和模板函数的方式。在C++标准中,STL被组织为13个头文件:

<algorithm>、<deque>、<functional>、<iterator>、<vector>、<list>、<map>、<memory>、<numeric>、<queue>、<set>、<stack>、<utility>


2.STL的组件(6部分):容器、迭代器、算法、仿函数、内存配置器、配接器。

迭代器的分类:双向迭代器、随机存取迭代器

STL中的算法:搜索、排序、复制、修改、数值运算。

STL中大量使用仿函数,仿函数具有泛型编程强大威力和纯粹抽象概念的特征!

                                            图1STL结构图

1.     容器

STL容器分为两大类:序列式容器(vector、list、deque)、关联式容器(set、map、multiset、multimap)

名称

说明

vector<T>

向量

list<T>

双向链表容器,实现了标准C++数据结构中链表的所有功能

queue<T>

队列容器,实现了标准C++数据结构中队列的所有功能

stack<T>

栈容器,实现了标准C++数据结构中栈的所有功能

deque<T>

双端队列,实现了标准C++数据结构中队列的所有功能

priority_queue<T>

一种按值排序的队列容器

set<T>

一种集合容器

multiset<T>

一直允许出现重复元素的集合容器

map<key,val>

一种关联数组容器

multimap<key,val>

一种允许出现重复key值的关联数组容器


1.     STL算法

STL中的所有算法都是基于模板实现的。这些算法都定义在标准名空间std内。通过包含<algorithm>来获得使用权。

部分常见算法:

for_each()

find()

find_if()

count()

count_if()

replace()

replace_if()

copy()

unique_copy()

sort()

equal_range()

merge()


3.     迭代器

迭代器就是指示器。迭代器为访问容器内的元素提供了通用的方法,类似于C++的指针。

当参数化类型是C++的内部类型时,迭代器即C++指针。

STL定义了5种类型的迭代器,每种容器都支持某种类别的迭代器。

常见的迭代器类别包括:输入、输出、前向、双向、和随机访问


4.     仿函数

C++中,函数调用一般使用指针(函数地址),当需要调用函数时,只需告诉函数的地址即可。

static int cmp(int* i, int* j){ return (*i - *j); }
当需要调用上面定义的函数时,只需要提供函数的地址即可:
qsort(1, 10, sizeof(int), cmp);

这种方法的缺点就是效率低,为了提高效率,STL定义了仿函数的概念。

定义仿函数,其特征就是使用operator()来定义,

struct three_mul
{
	bool operator()(int& v)
	{
		return (v % 3 == 0);
	}
};

通过运算符定义能显著提高效率。

for_each(muvector.begin(), myvector.end(), three_mul);

5.  内存配置器

STL包括底层的内存分配和释放。allocator

配接器可以实现不同类之间的数据转换。最常用的配接器有istream_iterator:提供了函数copy的接口。

adapter对于STL来说非常重要。

STL提供了3中容器配接器:stack<Container>、queue<Container>、deque<Container>



二、string字符串

C++从C继承的字符串概念仍然是以’\0’为结束符的char数组。

在STL库中,basic_string有两个预定义类型:包含char的string类型和包含wchar的wstring类型!

typedef basic_string<char, char_traits<char>, allocator<char> >
	string;
typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> >
	wstring;

字符串库简介、字符的特点、字符串类(basic_string)、字符串通用函数、字符串连接、字符串I/O、搜索和查找、字符串迭代器、字符串配置器。

配置器的作用就是为容器开辟内存!

配置器最早是为了将内存模型抽象化而提出来的。所有内存配置器分配内存是按对象的个数而不是按字节数来分配的,区别于new和new[]操作符。

配置器实现了将算法、容器、与物理存储细节相隔离。

配置器提供了一套分配与释放内存的标准方式,并提供用作指针类型和引用类型的标准名字。

配置器是一种纯粹的抽象,只要行为上像分配器的类型都可以看作是配置器。

 

C++ STL提供了标准分配器。

basic_string模板以及string类均提供了对常见配置器的相关支持。

class Allocator=allocator<char>


2.string类方法汇总:

函数名

功能

构造函数

生成或复制字符串

析构函数

销毁字符串

赋值=,assign

赋予新值

swap

交换两字符串对象的内容

+=,append(),push_back()

在尾部追加字符串

empty()

判断字符串是否为空

capacity()

返回字符容量

reserve()

预留内存以存储一定数量的字符

[]、at()

下标访问一个字符

>>、getline()

从stream中读取字符串

<< 

将字符串值写入流对象

insert()

插入字符、字符串

erase()

删除字符

clear()

删除全部字符

resize()

改变字符数量

replace()

替换字符

+

串联字符串

==、!=、<、<=、>、>=、compare()

按字典顺序比较字符串值大小

size()、length()

返回字符数量

max_size()

返回一个string对象能存的最大字符个数

copy()

将内容复制为一个C-string

c_str()

返回C风格C-string字符串

data()

将内容以字符数组形式返回

substr()

返回子字符串

find()

搜寻某个字符或子串

begin()、end()

正向迭代器

rbegin()、rend()

提供逆向迭代器

get_allocator()

返回配置器

三、vecto

参考资料:http://www.cplusplus.com/reference/vector/vector/?kw=vector

1. 序列式容器vector类模板

  • vector对象的定义;
  • vector对象的初始化(默认无参构造函数、带参构造函数、指针迭代器区间、复制构造);
  • vector容器的大小(size)和容量(capacity)
  • vector类的成员函数:

  1. 是否为空:empty()      //size=0
  2. 遍历vector:vector<T>::iterator和at()函数
  3. 元素访问方法:at()、[]、front()、back()
  4. 使用算法:for_each()函数、count()函数、count_if()函数[仿函factor]
  5. 插入元素:push_back()插到末尾、使用insert()函数将元素对象插入到vector任意位置。
  6. 删除元素:pop_back()、erase()、clear();[算法库的remove()]
  7. 交换对象swap():用于两个vector型容器(二者类型最好相同)之间元素互换。

  • 元素查找和搜索:STL的通用算法:find()、find_if()
  • 元素排序:使用STL的通用算法sort()、qsort()。vector类没有提供排序的成员函数。
  • vector<bool>:专门用于bool型,位运算等。
vector定义于标准名空间std内,定义在头文件<vector>中
支持随机访问,vector迭代器是随机存取迭代器,适用于任何STL算法
相当于动态数组
在末端插入或删除元素:vector性能相当好!

vector可以实现数据结构中的队列、数组、堆栈的所有功能

// TEMPLATE CLASS vector
template<class _Ty,
	class _Alloc = allocator<_Ty> >
	class vector
		: public _Vector_alloc<!is_empty<_Alloc>::value,
			_Vec_base_types<_Ty, _Alloc> >
	{	// varying size array of values

...
}
vector中的元素可以是任意类型 T(只要具备可设置setValue和可复制=两个属性)
第二个模板参数是关于空间配置器设置的,用于定义内存模型,默认内存模型是C++标准库提供的allocator.

参考:https://blog.csdn.net/linwh8/article/details/51386430

vector类介绍

According to cplusplus.com,

Vectors are sequencecontainers representing arrays that can change in size.(序列容器)

Just like arrays, vectorsuse contiguous storage locations for their elements, which means thattheir elements can also be accessed using offsets on regular pointers to itselements, and just as efficiently as in arrays.* But unlike arrays, their sizecan change dynamically, with their storage being handled automatically by thecontainer*.

Internally, vectors use a dynamically allocated array to store their elements.This array may need to be reallocated in order to grow in size when newelements are inserted, which implies allocating a new array and moving allelements to it. This is a relatively expensive task in terms of processingtime, and thus, vectors do not reallocate each time an element is added to thecontainer.

Instead, vectorcontainers may allocate some extra storage to accommodate for possible growth,and thus the container may have an actual capacity greater than the storagestrictly needed to contain its elements (i.e., its size). Libraries can implement different strategiesfor growth to balance between memory usage and reallocations, but in anycase, reallocations should only happen at logarithmically growing intervals ofsize so that the insertion of individual elements at the end of the vector canbe provided with amortised constant time complexity (see push_back).

Therefore, compared to arrays, vectorsconsume more memory in exchange for the ability to manage storage and growdynamically in an efficient way.

Compared to the other dynamic sequencecontainers (deques, lists and forward_lists), vectors are very efficientaccessing its elements (just like arrays) andrelatively efficient adding or removing elements from its end. For operationsthat involve inserting or removing elements at positions other than the end,they perform worse than the others, and have less consistent iterators andreferences than lists and forward_lists.(如果要像数组那样,在任意位置存取,应该用array数组

array<int, 100> myArray;  // #include<array>

分析:

(1)vector是array的升级版

vector是一个sequence容器,是array的升级版,主要因为vector能高效地对内存进行管理以及动态增长。但是,vector其实就是将array和方法封装形成的一个类。

(2)vector容器的内存管理

vector的容器大小可以动态增长,但是并不意味着每一次插入操作都进行reallocate。内存的分配与释放耗费的资源是比较大的,因此应当减少它的次数。与此同时,这也就意味着容器的容量(capacity)与容器目前容纳的大小(size)是不等的,前者应大于后者。

补充:上文也说了,对于vector内存的增长有很多strategies,例如第一次增长我增加2个内存单位,第二次增长我增加4个内存单位,第三次,第四次,… 第n次我增长2^n(前提是vector内存不够时再分配),这样也就大大减少了reallocate的次数。

(3)vector容器的意义

然后,vector虽然相对于array消耗了更多的内存,但是却实现了对内存的高效管理和增长,这种消耗是值得的。

(4)vector容器与其他容器的比较

与其他的sequence容器比较(如list,dequeue),vector访问元素的效率较高,但是对于增加与删除操作就不如其他两个容器了。

补充:

(5)vector的容纳对象

vector能容纳绝大多数类型的对象作为它的元素,但是因为引用不是对象,所以不存在包含引用的vector,即引用不能作为vector的对象。并且,vectot容纳的对象也可以是vector,但是有一点要注意,便是在这种情况下vector容器定义的格式:

// 早期c++标准
vector<vector<int> > // 倒数两个尖括号之间要加空格
// c++11
vector<vector<int>>  // 倒数两个尖括号之间无需加空格

几种容器操作的时间复杂度:

container

access

insert or erase

vector

O(1)

O(n^2)

list

O(n)

O(n)

dequeue

O(n)

O(n)

1.     vector的几种初始化及赋值方式:

(1)      不带参数的构造函数初始化:

//初始化一个size为0的vector
vector<int> abc;
(1)	vector非调用构造函数的初始化;
vector<int> Vector = {1, 2, 3, 4, 5};
// or
vector<int> Vector{1, 2, 3, 4, 5};
// compare
vector<int> Vector(10);
vector<int> Vector(10, 5);

我们可以这样理解:如果vector对象后带的是圆括号,则调用vector的构造函数;如果是花括号,优先考虑列表初始化。如果发现类型不匹配,无法构成列表初始化,则再考虑调用构造函数。 

vector<string> Vector{10};
vector<string> Vecytor{10, "hi"};

此时,由于类型不匹配,调用vector构造函数。

(2) 带参数的构造函数初始化

//初始化size,但每个元素值为默认值
vector<int> abc(10);    //初始化了10个默认值为0的元素
//初始化size,并且设置初始值
vector<int> cde(10,1);    //初始化了10个值为1的元素

(3) 通过数组地址初始化(相当于迭代器区间初始化)

int a[5] = {1,2,3,4,5};
//通过数组a的地址初始化,注意地址是从0到5(左闭右开区间)
vector<int> b(a, a+5);

(4) 通过同类型的vector初始化

vector<int> a(5,1);
//通过a初始化
vector<int> b(a);

2. vector类常用操作:

操作

作用

(constructor)

Construct vector

(destructor)

Vector destructor

operator=

Assign content

begin

Return iterator to beginning

end

Return iterator to end

rbegin

Return reverse iterator to reverse beginning

rend

Return reverse iterator to reverse end

cbegin (c++11)

Return const_iterator to beginning

cend (c++11)

Return const_iterator to end

crbegin (c++11)

Return const_reverse_iterator to reverse beginning

crend (c++11)

Return const_reverse_iterator to reverse end

size

Return size

max_size

Return maximum size

resize

Change size

capacity

Return size of allocated storage capacity

empty

Test whether vector is empty

reserve

Request a change in capacity

shrink_to_fit (c++11)

Shrink to fit

operator[]

Access element

at

Access element

front

Access first element

back

Access last element

data (c++11)

Access data

assign

Assign vector content

push_back

Add element at the end

pop_back

Delete last element

insert

Insert elements

erase

Erase elements

swap

Swap content

clear

Clear content

emplace (c++11)

Construct and insert element

emplace_back (c++11)

Construct and insert element at the end

get_allocator

Get allocator



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于计算机专业的学生而言,参加各类比赛能够带来多方面的益处,具体包括但不限于以下几点: 技能提升: 参与比赛促使学生深入学习和掌握计算机领域的专业知识与技能,如编程语言、算法设计、软件工程、网络安全等。 比赛通常涉及实际问题的解决,有助于将理论知识应用于实践中,增强问题解决能力。 实践经验: 大多数比赛都要求参赛者设计并实现解决方案,这提供了宝贵的动手操作机会,有助于积累项目经验。 实践经验对于计算机专业的学生尤为重要,因为雇主往往更青睐有实际项目背景的候选人。 团队合作: 许多比赛鼓励团队协作,这有助于培养学生的团队精神、沟通技巧和领导能力。 团队合作还能促进学生之间的知识共享和思维碰撞,有助于形成更全面的解决方案。 职业发展: 获奖经历可以显著增强简历的吸引力,为求职或继续深造提供有力支持。 某些比赛可能直接与企业合作,提供实习、工作机会或奖学金,为学生的职业生涯打开更多门路。 网络拓展: 比赛是结识同行业人才的好机会,可以帮助学生建立行业联系,这对于未来的职业发展非常重要。 奖金与荣誉: 许多比赛提供奖金或奖品,这不仅能给予学生经济上的奖励,还能增强其成就感和自信心。 荣誉证书或奖状可以证明学生的成就,对个人品牌建设有积极作用。 创新与研究: 参加比赛可以激发学生的创新思维,推动科研项目的开展,有时甚至能促成学术论文的发表。 个人成长: 在准备和参加比赛的过程中,学生将面临压力与挑战,这有助于培养良好的心理素质和抗压能力。 自我挑战和克服困难的经历对个人成长有着深远的影响。 综上所述,参加计算机领域的比赛对于学生来说是一个全面发展的平台,不仅可以提升专业技能,还能增强团队协作、沟通、解决问题的能力,并为未来的职业生涯奠定坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值