STL容器基础 - 0

STL(standard Template Library  -- 标准模板库 -- 提高复用性

STL从广义上分为: 容器(conainer)、算法(algorithm)、迭代器(iterator);容器和算法通过迭代器来进行无缝衔接;STL几乎所有的代码都采用了类模板或函数模板。

STL六大组件:容器、算法、迭代器、仿函数、适配器、空间配置器

1、容器:用来存放各种数据结构:vector、deque、list、set、map等,用来存放数据

2、算法:各种常用的算法:sort、find、copy、for_each

3、迭代器:充当容器和算法连接的工具

4、仿函数:行为类似函数,可作为算法的某种策略(可通过仿函数指定排序类型)

5、适配器:一种用来修饰容器或者仿函数或迭代器接口的东西

6、空间配置器:负责空间的配置和管理

vector

初识vector(STL中常用的容器) 可以理解为数组,称为单端数组(只能在一段进行操作);和普通数组的区别是:vector是动态扩展,而普通数组是静态扩展。

动态扩展是指:把原来的空间释放掉,在重新开辟一块比原来空间大的空间 用来存放数据

//存放内置数据类型
#include<vector>
vector <int> v;
v.push_back(20);

//通过迭代器访问
for(vector<int> :: iterator v1 = v.begin(); v1 != v.end(); v1++)
{
      cout << *v1 << " " ; }
//创建了一个迭代器v1指向 容器的开始, 迭代器本质上是一个指针,对它解引用可以拿到数据

//利用for_each算法输出

for_each(v.begin(),v.end(),myprintf); // 通过for_each算法 来实现打印

//myprintf需要实现

void myprintf(int val)
{
   cout << val << endl;
}

容器中可以嵌套容器,在使用迭代器时,需要注意解引用操作

vector容器构造和赋值

#include<vector>
vector <int> v; //默认构造函数
vector<int> v1(v); // 拷贝构造
vector<int> v2(v1.begin(),v1.end());  //区间构造
vector<int> v3(10,100); //n个元素构造,  将10个100构造到容器v3中

//vector赋值

vector<int> v; 
v.push_back(10); //插入数据10
vector<int> v1;  
v1 = v ; //拷贝赋值

vector<int> v2; 
v2.assign(v1.begin(),v1.end()); //区间赋值

vector<int> v3;
v3.assign(10,100); //n个元素赋值

vector容量和大小

empty(); 判断容器是否为空      

capacity(); 容器的容量

size();容器的大小

resize(int num ,elem); 重新指定容器的大小,若多出的部分没有指定值,默认为0填充,指定的大小缩短,超出的部分会被删除

#include<vector>
vector<int> v1;
 v1.push_back(10);
  v1.push_back(20);
 v1.push_back(66);

if(v1.empty())
{
   cout << "v1为空";
}
else
{
   cout << "v1不为空,v1的大小: "  << v1.size() << endl;
}

cout << "v1的容量为: " << v1.capacity() << endl;

v1.size(10); //重新指定大小,多出的部分默认值填充

v1.size(2); //超出的部分会被删除

Vector插入和删除

#include<vector>
vector<int> v;
v.push_back(10);
v.push_back(20);

v,pop_back();

v.insert(v.begin(),10); //在容器开头插入一个10
v.insert(v.begin(),2,100);// 在容器开头插入两个 100

v.erase(v1.begin()); //删除迭代器开头元素
v.erase(v1.begin(),v1.end()); //删除区间

v.clear(); //清除容器中的元素

vector容器存取

#include<vector>
vector<int > v;
v.push_back(10);

cout << v[0] << endl; // [ ] 通过[ ] 访问

cout << v.at(0) << endl; //通过at访问

cout  << v.front() << endl; //访问第一个元素
cout << v.back() << endl; // 访问最后一个元素

vector互换容器: v1.swap(v2); //v1 和 v2互换

利用swap来收缩内存  v.resize(5); vector<int>(v).swap(v); 将容器互换从而达到收缩内存,

vector<int>(v) 是一个匿名对象, 匿名对象的大小就是重新压缩后的大小,和v容器空间互换,v的空间就换到了匿名对象里,匿名对象本行结束之后会被回收,

reverse(int len ) 预留空间    :减少动态扩展容量时的扩展次数,预留位置不初始化,元素不可以访问 v.reverse(10000);

deque

双端数组:可以对头端进行插入和删除操作

deque和vector的区别:

vector对于头部的插入删除效率低,数据量较大,效率越低,deque容器对头部的插入和删除速度比vector快, vector容器访问数据速度比deque快

deque的内部工作原理:

deque内部有个中控器,维护每段缓冲区的内容,缓冲区中存放真实数据,deque容器支持随机访问

deque赋值和构造

#include<deque>
deque<int> d1; //默认构造
deque<int> d2(d2); //拷贝构造
deque<int> d3(d1.begin(),d1.end()); //区间构造
deque<int> d4(10,100); // n个元素构造, 10个100元素

deque<int> d5;
d5 = d4; //拷贝赋值

deque<int> d6;
d6.assign(d5.begin(),d5.end()); //区间赋值

deque<int > d7;
d7.assign(10,1000); //10个1000赋值

deque大小操作

empty();判断为空  size()返回元素个数; resize();重新制定大小

#include<deque>
deque<int> d;
d.push_back(10);
d.push_front(20);

if(d.empty())
{
cout << "  d为空 " <<endl;
}
else
{
   cout << "d不为空,d的大小: " << d.size() << endl;
}

d.resize(10,100); //重新指定大小为10,多出的部分用指定值100填充
d.resize(1); // 重新指定大小为1, 超出的部分会删除

注意:deque容器没有容量的概念

deque插入和删除

#include<deque>
deque<int> d;
d.push_back(10);
d.push_front(20);
d.push_front(30);

//头删和尾删
d.popfront();
d.popback();

//insert插入
d.insert(d1.begin(),100); // 在容器的开头插入数据100
d.insert(d1.begin(),2, 2000); //在容器的开头插入两个2000

d.insert(d1.begin(),d1.begin(),d1.end()); //在容器开头 插入一个区间

//erase删除
d.erase(d1.begin(),d.end()); //删除区间元素

d.clear(); // 清空容器中的数据

大部分操作与vector类似; 插入和删除的位置都是迭代器

deque数据访问 -- 下标访问 [ ] , at访问 ,front( ) 获取头元素, back() 获取尾元素

deque排序操作:sort(d1.begin(),d1.end()); 利用sort算法进行排序, 默认排序是 升序, 利用算法时需要包含头文件algorithm , 可以利用仿函数来指定排序类型,支持随机访问的容器都可以直接用 sort()排序

string容器

string本质:string是C++风格的字符串,而string本质上是一个类;

string和char*的区别:

char*是一个指针,string是一个类,内部封装了char*,管理这个字符串,是一个char*的型的容器

特点:

string类还封装了很多成员方法:查找find、拷贝copy、删除delete、替换replace、插入insert;string管理char*分配的内存,不用担心赋值越界,由类内部负责

string构造和赋值函数

#include<string>
string s1; //默认函数构造
const char* str = "abc"; 

string s2(str); 
string s3(s2); //拷贝构造

string s4(10,"a"); //n个元素构造

s1 = "hello c++"; //赋值

s2 = s1 ; //拷贝赋值

//assign赋值
s3.assign("world");

s4.assign(s3);

s5.assign("hello world", 5); //去前面五个元素赋值

s6.assign(10,"c"); //n个元素赋值

string拼接

#include<string>
string s1 = "hello"; 

s1+= " world"; 

string s2 = "nihao";

s1+= s2; //拼接

//assign拼接
string  s3 = "I";

s3.append("love");

s3.append(s2) ;

s3.append("LOL DOF", 0,3); //从第一个数开始,往后三个数拼接到s3字符串中

s3.append("WORLD",1); // 截取第一个字符

string查找和替换

find( );找到返回该字符串第一个字符在主串中的位置下标,未找到就返回-1;

replace();从字符串某个下标开始,将这个字符替换成指定的字符或字符串

rfind();与find不同是从右向左找,但是都是从左至右数

#include<string>
string s1 = "hello worldd";
int pos = s1.find("el"); //查找el字符串在s1中的位置 找到返回 第一个字符的在主串中的下标
//未找到返回-1

pos = s1.rfind(dd); //rfind是从左至右查找,从右至左数


s1.replace(1,3, "11111"); //从下标为1的字符开始数三个数,将其替换成指定内容 

compare函数比较两个字符串是否相等;s1.compare(s2) 将两个字符串各个位置上的字符进行比较,相等返回0

string的存取:[ ] 、 at访问

string删除和插入:insert 插入 、 erase删除,下标都是从0开始

string str  ="hello";
str.insert(1,"111"); //把下标为1的字符替换成 指定字符

str.erase(1,3); //删除下标为1开始之后的三个数

//都是下标为0开始

substr( ) 获取子串:

#include<string>
string str1 = "helllo";

string str2 = str1.substr(1,3); //从字符串下标为1的字符开始,截取三个字符存放到str2中

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值