活动地址:毕业季·进击的技术er
炎炎夏日,热浪中我们迎来了毕业季,这是告别,也是迈向新起点的开始,CSDN诚邀所有毕业生/学生/职场人士讲述毕业季的故事,分享经验和技术er进攻之路,等你写!可以选择适合自己的相应身份,从以下相关内容开始写作,也可以从自己的经历出发,参与提交符合活动主题的文章题目。
毕业生 | 在校生 | 职场人 |
---|---|---|
毕业后下落:继续读研还是直接就业? | 现在有多大?专业是什么?这个专业让你Get到哪些新技能? | 到目前为止,我已经毕业好几年了?我学的是什么专业? |
大学四年给你留下了深刻的印象bug追查记 | 你决定从哪一刻开始学习编程语言? | 你从事过这个专业吗?目前从事的行业和职业?你还记得介绍导师吗?给大家介绍一下。 |
大学期间技术学习最有成就感的事情? | 进入大学的第一行代码是什么? | 从毕业生到职场IT人,最大的感受是什么? |
大学最遗憾的事/未完成的事? | 学习中最大的收获/困难是什么? | 你认为职场新人应该如何选择毕业季的工作? |
你对即将进入的行业有什么期望? | 大学期间的学习目标是什么?未来的职业规划是什么? | 技术在工作中er如何在技术领域快速成长? |
个人展望/未来规划毕业后? | 在技术学习过程中遇到的最大问题是什么? | 你忍不住和朋友分享了哪些开源项目? |
如何看待毕业生面临的就业困难? | 目前参加了多少编码比赛,获得了多少证书?你能介绍一下吗? | 技术在工作中做过的最有成就感的事情? |
… | 下一个学习计划/实习计划? | 你觉得程序员35岁的瓶颈怎么样? |
… | … | 想对毕业生/在校生说些什么? |
… | … | … |
活动地址:毕业季·进击的技术er
一、STL基本概念
1、STL概述
STL(标准模板库),STL广义上分为:容器(container) 算法(algorithm) 迭代器(iterator),从根本上说,STL是一些“容器”的集合,这些“容器”有list,vector,set,map等,STL也是算法和其他组件的集合。
2、STL六大组件
容器(vector,list…) 算法(sort,find…) 迭代器(扮演容器算法之间的胶合剂,所有STL容器都有自己的专属迭代器) 仿函数(行为类似函数,可作为算法的某种策略) 适配器(用于修改容器或仿函数或迭代器接口的东西) 空间配置器(空间配置与管理)
容器通过空间配置器获得数据存储空间,算法通过迭代器存储容器中的内容,仿函数可以帮助算法完成不同策略的变化,适配器可以修改仿函数。
在开发STL有一群人开发容器,有一群人开发算法,他们分工合作,但如果每个人都做,容器和算法可能不会集成在一起,然后开发算法对开发容器的人说,你给我一个迭代,这样他们就可以分工合作,所以
3、容器
容器可以嵌套,分为
- (排序,如Vector,List,Deque容器)容器中元素的位置是有序的,如顺序表
- 元素在容器中的位置是固定的,如哈希表
4、迭代器
iterator模式定义:在不暴露容器内部显示模式的情况下,提供一种方法来访问容器中包含的每个元素。(迭代器可以理解为指针,指针基本上可以用于迭代器,事实上,迭代器是一个类,包装了一个指针)
4、算法
通过有限的步骤解决问题,如何搜索、排序等 STL模板函数提供约100个实现算法
当容器与算法接触时,需要迭代器的帮助
5.迭代器基本语法
1.迭代器的声明
容器提供的迭代器 v.begin()返回开始的迭代器,但是由于容器存放的数据类型不一样,因此迭代器可能会有所差异,因此在定义一个迭代器对象的时候需要指明迭代器的类型, 比如容器是vector< int >a ;然后声明迭代器对象是容器声明和迭代器 vvector< int >::iterator begin = c.begin();
二、使用迭代器
迭代器对象可以被认为是一个指针,容器存储什么数据,当它被取出时(*begin)例如,数据类型是什么,vector< Person >,想要访问Perons的age,是(*Person).age而不是(*Person)->age,因为是存放的Person,而不是Person *
嵌套打印
二、STL常用容器
1、string容器
- 。string封装了char*,管理这个字符串,也就是说,string对象中有指针,是指针char*类型的容器
- ,例如,搜索、复制、删除、替换、插入
- string管理char*每次分配内存string复制取值均由string负责维护,不用担心复制越界和取值越界
2、String常用api
1)声明
string s=“aaaa”; 对于string,如果使用[]访问,越界将直接挂断,不会抛出异常,但如果使用at方式,出现越界会向上抛出异常。
2)拼接 =
3)追加appen
const char *s33="aaaaaaa";
s.append(s33);//全部追加char*
s.append(s33,2);//追加s2的前2个字符
string s44="aaaaaaa";
s.append(s44);//追加string类型
s.append(s44,0,4);//追加string的指定范围的字符
4)查找find
find是从前往后找,找第一次出现的位置,rfind是从后往前找。 第一个参数是目标,这个目标可以是char也可以是char*也可以是string,第二个参数是开始位置,第三个参数是终止位置
5)替换replace
第一个参数是起始位置,第二个参数是长度,第三个参数是替换成为的元素,可以是char*也可以是string。也就是前两个参数围成的区域会被割去换成第三个参数。注意第二个参数是长度
6)比较compare
(等于) = 返回 0
(大于) > 返回 1
(小于) < 返回 -1
string s1 = "abcd";
string s2 = "abcd2";
if (s1.compare(s2) == 0) cout << "两个字符串相等";
else cout << "两个字符串不相等";
7)截取字符串substr
两个参数为区间,第二个参数默认为最后
8)插入insert和删除erase
insert第一个参数是位置,第二个参数是插入的字符串,字符串可以是char*也可以是string 删除erase两个参数第一个是开始,第二个是删除的个数,第二个参数默认是最后
3、vector容器
vector< int>v;v是一个对象,v的地址是对象的地址,并不是第一个元素的地址,看第一个元素的地址应该是&(v[0]) 1、vector是单口容器,是占得连续的内存空间 2、vector提供了两组迭代器,分别是v.begin()、v.end()指向了vector的第一个元素和最后元素的下一个位置,另外一组是v.rbegin()、v.rend(),分别指向了最后一个元素和第一个元素的前面的位置。 3、vector提供了push_back()从末尾插入元素,也提供了pop_back()弹出最后一个元素,建议使用这个,虽然也提供了insert在指定位置插入元素 4、对于string,如果使用[]方式访问,出现越界将会直接挂掉不会抛异常,但是如果使用at方式,出现越界会向上抛出异常,对于vector同样这样。
vector动态增长原理
当插入新元素时,如果空间不足,那么vector会重新申请更大的一块内存空间,将原空间数据拷贝到新空间,释放旧空间的数据,再把新元素插入新申请空间。 这里有个看申请了多少次空间的方法
int *address=NULL;
for(1-》1000000)//for循环这么多次 增加元素
if(address!=&(v[0])) //一个地址记录第一个元素的地址
{
address=&(v[0]);//如果发现第一个元素的地址发生变化
cout++;//那么肯定是又重新申请内存了,这里++
}
3、vector常用api
1)vector构造函数
1、拷贝构造函数 2、拷贝指定区间的元素
vector<int> v1; //构造int类型的空容器
vector<int> v2(10, 2); //构造含有10个2的int类型容器
vector<int> v3(v2); //拷贝构造int类型的v2容器的复制品
v3=v4;//因为有=的重载
vector<int> v4(v2.begin(), v2.end()); //使用迭代器拷贝构造v2容器的某一段内容
string s("hello world");
vector<char> v5(s.begin(), s.end()); //拷贝构造string对象的某一段内容
下面是常用的将数组复制到vector中的方法
2)插入push_back和删除元素pop_back
v.push_back(1); //尾插元素1
v.pop_back(); //尾删元素
3)swap交换两个容器的数据空间
交换两组的数据空间实际上是将指针交换了,空间并没有变化
vector<int> v1(10, 1);
vector<int> v2(10, 2);
v1.swap(v2); //交换v1,v2的数据空间
4)size()获取容器有效元素个数
(注意和capacity的区别)
cout << v.size() << endl; //获取当前容器中的有效元素个数
4)capacity()获取当前容器的最大容量
容量和size可能不相等,当容器的容量不够时,它会申请更大的(不是+1个空间,避免重复复制)
cout << v.capacity() << endl; //获取当前容器的最大容量
5)resize改变容器中的有效元素个数
1、当所给值大于容器当前的size时,将size扩大到该值,扩大的元素为第二个所给值,若未给出,则默认为0。 2、当所给值小于容器当前的size时,将size缩小到该值,超过范围的元素将被删除。
vector<int>(v).swap(v);
为什么呢,vector(v)是初始化了一个匿名对象,初始化完成后通过swap交换空间,两个内存空间的指针发生了交换,然后匿名对象执行结束就会被销毁
6)at和[]
v.at(10);//越界会抛异常
v[10];//越界不会有异常,直接结束程序
7)front和back返回第一个和最后一个元素
v.front();
v.back();
8)insert插入元素和earse删除元素和clear清空vector
insert的位置参数只能是迭代器 vector支持随机访问,所以直接可以像下面这样直接+2
v1.insert(v1.begin(),10);//再开始位置插入10
v1.insert(v1.end(),10);//在结束位置插上10
v1.insert(v1.begin()+1,10);//在下标为1的位置插上10
earse位置参数也只能是迭代器 如果仅有一个参数,则只是删除指定位置的元素 如果有两个参数,则是指定的范围
v1.erase(v1.begin());
v1.erase(v1.begin()+2);
v1.erase(v1.begin(),v1.end());
v1.clear(0;
9)reserve和resize的区别
通过reserse函数改变容器的最大容量,resize函数改变容器中的有效元素个数。
reserve规则: 1、当所给值大于容器当前的capacity时,将capacity扩大到该值。 2、当所给值小于容器当前的capacity时,什么也不做。
resize规则: 1、当所给值大于容器当前的size时,将size扩大到该值,扩大的元素为第二个所给值,若未给出,则默认为0。 2、当所给值小于容器当前的size时,将size缩小到该值。
三、总结
1、STL是一些“容器”的集合,STL也是算法和其他一些组件的集合。STL的容器和算法的桥梁是迭代器 2、定义的string是一个对象,里面封装了char指针,也封装了很多方法,且不需要考虑内存释放和回收 3、不管是string还是vector,使用[]越界会挂掉,使用at()会抛出异常 4、string可以拼接string char char类型数据 5、string +=拼接 append追加 find查找 replace代替 compare比较 截取字符串substr 插入insert和删除erase 6、vector< int>v;v是一个对象,v的地址是对象的地址,第一个元素的地址应该是&(v[0]) 7、vector构造函数,有个按arr[]构造的方法 vector< int >v2(arr.begin(),arr.end()) 其它的构造v3=v4;vector v3(v2);vector v4(v2.begin(), v2.end());vector v2(10, 2);10个2 8、vector的常用函数插入push_back和删除元素pop_back,v1.swap(v2); //交换v1,v2的数据空间,size()获取容器有效元素个数,capacity()获取当前容器的最大容量,resize改变容器中的有效元素个数,