当前位置: 首页 > news >正文

上海网站空间租用建网站需要多少费用

上海网站空间租用,建网站需要多少费用,网站做伪原创收录,婚庆大气网站源码👦个人主页:Weraphael ✍🏻作者简介:目前学习C和算法 ✈️专栏:C航路 🐋 希望大家多多支持,咱一起进步!😁 如果文章对你有帮助的话 欢迎 评论💬 点赞&#x1…

在这里插入图片描述

👦个人主页:@Weraphael
✍🏻作者简介:目前学习C++和算法
✈️专栏:C++航路
🐋 希望大家多多支持,咱一起进步!😁
如果文章对你有帮助的话
欢迎 评论💬 点赞👍🏻 收藏 📂 加关注✨


目录

  • 一、什么是vector
  • 二、vector初始化
      • 2.1 默认构造函数(常见)
      • 2.2 构造函数将n个元素拷贝给本身
      • 2.3 拷贝构造函数(常见)
      • 2.4 区间拷贝
      • 2.5 数组方式
  • 三、迭代器的使用
      • 3.1 begin + end(常见)
      • 3.2 rbegin + rend
  • 四、遍历
      • 4.1 operator[]
      • 4.2 迭代器遍历
      • 4.3 范围for
  • 五、空间增长问题
      • 5.1 size
      • 5.2 empty
      • 5.3 resize
      • 5.4 reserve
      • 5.5 swap
  • 六、vector的插入与删除
      • 6.1 push_back - 尾插
      • 6.2 pop_back - 尾删
      • 6.3 insert - 插入
      • 6.4 erase - 删除pos位置的数据
      • 6.5 clear - 清空所有数据
  • 七、几个常用算法
      • 7.1 sort - 排序
      • 7.2 reverse
      • 7.3 find
  • 八、迭代器失效问题
      • 8.1 什么是迭代器失效
      • 8.2 为什么string不存在迭代器失效问题
      • 8.3 几个常见的迭代器失效样例
      • 8.4 如何解决迭代器失效问题

一、什么是vector

  • vector容器和数组非常相似,与普通数组的区别:数组是静态空间,而vector可以动态扩展
  • 动态扩展并不是在原空间之后续接新空间,而是找更大的内存空间,然后将原数据拷贝新空间,释放原空间
  • 使用vector容器需要包含头文件:#include <vector>
  • vector可以存储多种不同的数据类型,是因为它是一个模板容器
    在这里插入图片描述
    通过使用模板参数,我们可以在vector中指定要存储的数据类型,例如:
vector<int> vi // 整型容器
vector<char> vc // 字符型容器
vector<double> vd // 浮点型容器
vector<string> vs // string类型容器
vector<vector<int>> // 本质是二维数组
// 等等...

类模板实例化与普通类的实例化不同,类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<>中即可,而普通类的类名就是类型。

注意:需要注意数据类型的统一性。例如,如果创建了一个存储整数的vector,就应该只向其中存储整数类型的数据,否则可能会出现类型错误或数据损坏的问题。

二、vector初始化

2.1 默认构造函数(常见)

#include <iostream>
#include <vector>
using namespace std;
int main()
{// 默认构造函数vector<int> v;return 0;
}

默认构造的对象,sizecapacity都为0。

在这里插入图片描述

2.2 构造函数将n个元素拷贝给本身

【函数原型】

vector<T> v(n,elem);

【代码示例】

#include <iostream>
#include <vector>
using namespace std;int main()
{// 构造函数将n个元素拷贝给本身// 将3个100拷贝给本身vector<int> v(3, 100);for (int i = 0; i < v.size(); i++){cout << v[i] << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

2.3 拷贝构造函数(常见)

【函数原型】

vector (const vector& x);

【代码示例】

#include <iostream>
#include <vector>
using namespace std;int main()
{// 构造函数将3个100拷贝给本身vector<int> v1(3, 100);cout << "v1:";for (int i = 0; i < v1.size(); i++){cout << v1[i] << ' ';}cout << endl;// 拷贝构造函数// v2是v1的副本vector<int> v2(v1);cout << "v2:";for (int i = 0; i < v2.size(); i++){cout << v2[i] << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

2.4 区间拷贝

【函数原型】

vector(v.begin(),v.end());

【代码示例】

#include <iostream>
#include <vector>
using namespace std;int main()
{// 构造函数将n个元素拷贝给本身// 将5个100拷贝给本身vector<int> v1;// 写入1 2 3 4 5v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.push_back(5);// 区间拷贝// 拷贝v1对象中的2、3、4、5vector<int> v2(v1.begin() + 1, v1.end());cout << "v2:";for (int i = 0; i < v2.size(); i++){cout << v2[i] << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

2.5 数组方式

#include <iostream>
#include <vector>
#include <string>
using namespace std;int main()
{vector<int> v1{ 1,2,3,4,5,6 };vector<char> v2{ 'h','e','l','l','o' };vector<string> v3{ "hello", "vector" };return 0;
}

【输出结果】

在这里插入图片描述

三、迭代器的使用

3.1 begin + end(常见)

大家可以认为迭代器是指针。begin指向第一个数据的位置,end指向最后一个数据的下一个位置

在这里插入图片描述

【代码示例】

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<char> v;// 插入abcdefgv.push_back('a');v.push_back('b');v.push_back('c');v.push_back('d');v.push_back('e');v.push_back('f');v.push_back('g');vector<char>::iterator begin = v.begin();// begin指向第一个元素,对齐解引用就能得到cout << "第一个元素为:" << *begin << endl;vector<char>::iterator end = v.end();// end指向最后一个元素的下一个位置cout << "最后一个元素为:" << *(end - 1) << endl;return 0;
}

【输出结果】

在这里插入图片描述

3.2 rbegin + rend

rbeginrend是反着来的。rbegin指向的是最后一个元素,rend指向的是第一个元素的前一个位置
在这里插入图片描述

【代码示例】

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<char> v;// 插入abcdefgv.push_back('a');v.push_back('b');v.push_back('c');v.push_back('d');v.push_back('e');v.push_back('f');v.push_back('g');// vector<char>::iterator 如果认为太长// 可用autoauto vci = v.rbegin();// vci指向最后一个元素cout << "最后一个元素:" << *vci << endl;auto vcc = v.rend();// vcc指向第一个元素的前一个位置// 对其-1。就指向第一个元素cout << "第一个元素" << *(vcc - 1) << endl;return 0;
}

【输出结果】

在这里插入图片描述

四、遍历

4.1 operator[]

在这里插入图片描述

vector底层重载了下标访问操作符[],因此可以像数组一样变量

#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<char> v;// 插入abcdefgv.push_back('a');v.push_back('b');v.push_back('c');v.push_back('d');v.push_back('e');v.push_back('f');v.push_back('g');// operator[]for (int i = 0; i < v.size(); i++){cout << v[i] << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

4.2 迭代器遍历

#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<char> v;// 插入abcdefgv.push_back('a');v.push_back('b');v.push_back('c');v.push_back('d');v.push_back('e');v.push_back('f');v.push_back('g');// 迭代器vector<char>::iterator begin = v.begin();while (begin != v.end()){cout << *begin << ' ';begin++;}cout << endl;// 以上用for循环也是可以的for (vector<char>::iterator begin = v.begin(); begin != v.end(); begin++){cout << *begin << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

4.3 范围for

string类时,我们讲过 范围for的底层是迭代器。

#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<char> v;// 插入abcdefgv.push_back('a');v.push_back('b');v.push_back('c');v.push_back('d');v.push_back('e');v.push_back('f');v.push_back('g');// 范围forfor (auto x : v){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

五、空间增长问题

5.1 size

功能:获取数据的有效个数

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v{ 1,2,3,4 };cout << "个数为:" << v.size() << endl;for (int i = 0; i < v.size(); i++){cout << v[i] << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

5.2 empty

功能:判断容器是否为空。如果为空返回1,否则返回0

#include <iostream>
#include <vector>
using namespace std;int main()
{// 默认构造默认有效个数size为0vector<int> vi;cout << "vi:" << vi.empty() << endl;vector<char> vc{ 'h', 'e', 'l', 'l','o' };cout << "vc:" << vc.empty() << endl;return 0;
}

【输出结果】

在这里插入图片描述

5.3 resize

【函数原型1】

resize(int num);

功能:重新指定容器的长度为num

情况1:若有效数据size > num,则会保留前num个,剩下的删除

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v{ 1,2,3,4,5,6 };cout << "改变之前的长度:" << v.size() << endl;// 重新指定容器长度// 保留前3个v.resize(3);cout << "改变后的长度:" << v.size() << endl;cout << "改变后的内容为:";for (int i = 0; i < v.size(); i++){cout << v[i] << ' ';}cout << endl;return 0;
}

【程序结果】

在这里插入图片描述

【函数原型2】

resize(int num, elem);

情况2:若num > size,则会增加有效长度。如果不指定第二个参数,默认增加的内容是0

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v1{ 1,2,3,4 };v1.resize(6);// 增加了2个,不指定第二个参数默认是0for (auto x : v1){cout << x << ' ';}cout << endl;vector<char> v2{ 'h','i' };v2.resize(6, 'x');for (auto x : v2){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

5.4 reserve

功能:改变vector容器的容量。一般都是扩容。

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;int capacity = v.capacity();for (int i = 0; i < 100; i++){// 插入100个数据v.push_back(i);// v.capacity是输出当前容量的if (capacity != v.capacity()){capacity = v.capacity();cout << "容量改变:" << capacity << '\n';}}return 0;
}

【输出结果】

在这里插入图片描述

通过以上代码我们发现:vs下的容量是按1.5倍增长的g++是按2倍增长的。

然后我们再把以上代码拿到Linux环境下测试:

在这里插入图片描述

我们发现:Linux下使用的vector是按照2倍方式扩容。

因此,如果已经确定vector中要存储元素大概个数,可以提前将空间设置足够就可以避免边插入边扩容导致效率低下的问题了。

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;int capacity = v.capacity();// 提前开好大小为100的容量v.reserve(100);for (int i = 0; i < 100; i++){// 插入100个数据v.push_back(i);// v.capacity是输出当前容量的if (capacity != v.capacity()){capacity = v.capacity();cout << "容量改变:" << capacity << '\n';}}return 0;
}

【输出结果】

在这里插入图片描述

或者还能这样开空间:

在这里插入图片描述

5.5 swap

【函数原型】

swap(vec); // 将vec与本身的元素互换

【代码示例】

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v1{1,2,3,4,5,6};v1.reserve(100);cout << "交换前:" << endl;cout << "v1:";for (auto x : v1){cout << x << ' ';}cout << endl;vector<int> v2{ 7,8,9,10,11, 12 };cout << "v2:";for (auto x : v1){cout << x << ' ';}cout << endl;cout << "v1的容量" << v1.capacity() << endl;cout << "v2的容量" << v2.capacity() << endl;// 交换v1.swap(v2);cout << "交换后:" << endl;cout << "v1:";for (auto x : v1){cout << x << ' ';}cout << endl;cout << "v2:";for (auto x : v1){cout << x << ' ';}cout << endl;cout << "v1的容量" << v1.capacity() << endl;cout << "v2的容量" << v2.capacity() << endl;return 0;
}

【输出结果】

在这里插入图片描述

通过以上发现:swap不仅可以交换容器内容,同时还达到实用的收缩内存效果

六、vector的插入与删除

6.1 push_back - 尾插

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;// 尾插1、2、3、4v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);for (auto x : v){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

6.2 pop_back - 尾删

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;// 尾插1、2、3、4v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);for (auto x : v){cout << x << ' ';}cout << endl;// 删掉4v.pop_back();for (auto x : v){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

6.3 insert - 插入

【函数原型1】

iterator insert (iterator position, const value_type& val);

注意:insert是要配合迭代器使用的!

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;// 尾插1、2、3、4v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);for (auto x : v){cout << x << ' ';}cout << endl;// 头插一个6v.insert(v.begin(), 6);for (auto x : v){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

【函数原型2】

void insert (iterator position, size_type n, const value_type& val);

【代码样例】

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;// 尾插1、2、3、4v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);for (auto x : v){cout << x << ' ';}cout << endl;// 尾插4个6v.insert(v.end(), 4, 6);for (auto x : v){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

6.4 erase - 删除pos位置的数据

【函数原型1】

erase(const iterator pos);

注意:erase也是要配合迭代器使用的

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);// 删除最后一个数据v.erase(v.end() - 1);for (auto x : v){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

【函数原型2】

erase(const iterator start,const iterator end)

功能:删除某个区间的数据

【代码示例】

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);// 清空数据v.erase(v.begin(), v.end());for (auto x : v){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

除了以上方式可以清空数据,clear同样也行

6.5 clear - 清空所有数据

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.clear();for (auto x : v){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

七、几个常用算法

注意:使用库里的算法需要加上头文件#include <algorithm>

7.1 sort - 排序

#include <iostream>
#include <vector>
using namespace std;
#include<algorithm>int main()
{vector<int> a{ 4,7,1,0,5,3, 2 };// 从小到大sort(a.begin(), a.end());for (auto x : a){cout << x << ' ';}cout << endl;// 从大到小sort(a.rbegin(), a.rend());for (auto x : a){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

7.2 reverse

#include <iostream>
#include <vector>
using namespace std;
#include<algorithm>int main()
{vector<int> a{ 1,2,3,4,5,6 };//逆置reversereverse(a.begin(), a.end());for (auto x : a){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

7.3 find

注意:vector是没有提供find接口的。而我们知道vector是一个类似于数组的容器,因此如果想找一个数据,直接遍历即可。但是算法库提供了find

#include <iostream>
#include <vector>
using namespace std;
#include<algorithm>int main()
{vector<int> a{ 1,2,3,4,5,6 };// 查找4vector<int>::iterator pos = find(a.begin(), a.end(), 4);if (pos != a.end()){// 找到4就删掉a.erase(pos);}for (auto x : a){cout << x << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

八、迭代器失效问题

8.1 什么是迭代器失效

迭代器失效实际就是迭代器底层对应指针所指向的空间被销毁了,而使用一块已经被释放的空间,造成的后果是程序崩溃。即如果继续使用已经失效的迭代器,程序可能会崩溃。

8.2 为什么string不存在迭代器失效问题

string是一个特殊的容器,它是由字符组成的连续序列,类似于C语言的字符串。string类会动态地管理内部存储区域,确保足够的容量容纳字符串。当我们向string中插入或删除字符时,并不会导致整个字符串被复制到新的内存位置,因此迭代器不会失效。

对比vector,它是一个动态数组,它使用连续的内存存储元素。当我们向vector中插入元素时,如果导致当前内存不足以容纳所有元素,vector会重新分配更大的内存空间,并将所有元素复制到新的内存中。这样一来,原来指向旧内存中的元素的迭代器就会失效,因为它们指向的位置已经改变了。

8.3 几个常见的迭代器失效样例

当涉及到插入或删除操作时,我们需要注意vector迭代器的失效问题

  • 会引起其底层空间改变的操作,都有可能是迭代器失效,比如:resizereserveinsertpush_back
#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v{ 1, 2, 3 };// 1. 将有效元素个数增加到100个//   多出的位置使用6填充,操作期间底层会扩容v.resize(100, 6);// 2. reserve的作用就是改变扩容大小但不改变有效元素个数,// 操作期间可能会引起底层容量改变v.reserve(100);// 3. insert和尾插期间// 可能会引起扩容,而导致原空间被释放v.insert(v.begin(), 0);v.push_back(10);return 0;
}

以上操作可能会导致vector扩容,扩容就会导致旧空间被释放掉,而返回的迭代器是指向被释放的空间,如果再对迭代器进行使用,会引起代码崩溃。

  • 指定位置元素的删除操作
#include <iostream>
#include <vector>
using namespace std;int main()
{int a[] = { 1, 2, 3, 4, 5 };vector<int> v(a, a + sizeof(a) / sizeof(int));// 使用find查找4所在位置auto pos = find(v.begin(), v.end(), 4);// 删除pos位置的数据,v.erase(pos);// 预测打印5cout << *pos << endl;return 0;
}

【输出结果】

理论上删除了4*pos应该是5,可是为什么没有打印出来呢?

我们可以通过调试来观察:

在这里插入图片描述

当我再按F10,发现pos的地址变了:

在这里插入图片描述

理论上删除4后,5应该占据4的空间,然而地址却变了。因此导致了迭代器失效了。

那如果是删除最后一个数据,那么结果更加明显:

在这里插入图片描述

8.4 如何解决迭代器失效问题

在使用前,对迭代器重新赋值即可。

#include <vector>
#include <iostream>
using namespace std;
int main()
{vector<int> v{ 1,2,3,4,5,6,7,8,9,10};// 保留1 2 3// 剩下全删除vector<int>::iterator it = v.begin() + 3;while (it != v.end()){// 在使用之前重新赋值it = v.erase(it);}for (auto& x : v){cout << x << ' ';}cout << endl;return 0;
}

在这里插入图片描述

【输出结果】

在这里插入图片描述

http://www.yayakq.cn/news/817471/

相关文章:

  • 优秀网站 要素网站后台乱码
  • 网站后台管理系统哪个好2022今天出京入京最新通知
  • 创办网站需要什么推网站建设话术
  • 网站开发大多用什么编程语言网站建设能力
  • 网站推广话术100款禁用网站
  • asp网站 工具用什么网站搭建小说网站
  • 网站建设需要用到哪些软件国家住房城乡建设厅网站
  • 个人网站可以备案企业查询软件免费
  • 做特卖的网站有哪些如何免费推广网站
  • 做网站的专业叫什么网站小视频怎么做的
  • 建设了网站怎么管理系统怎么自己制作网站平台
  • 注册网站不用手机短信验证的网站的总体结构
  • 自己的服务器做网站17zwd一起做网站
  • 如何把网站设为正确建设中家教中介网站怎么做学员引流
  • 建站平台取名字哈尔滨 建设网站 科技
  • 上传下载网站建设商城建站报价方案
  • 东莞网站seo优化托管百度招商加盟
  • 山东省乡镇网站建设北京户外广告公司排名
  • 做编程网站深圳企业网络推广公司
  • 做家纺网站哪家好沧州网站制作网站
  • 深圳nft网站开发公司城阳网站改版
  • 白云区建网站网站设置怎么清除
  • excel网站链接怎么做wordpress网站主机名
  • 广州网站建设公司app开发公司未按照合同开发
  • 中国安能建设集团有限公司网站广告设计公司的进项有哪些
  • 常德建设网站动漫网站模板下载
  • 北洼路网站建设wordpress 选择题
  • 触摸屏网站建设培训网站开发怎么样
  • 资讯网站模版广州app制作
  • wordpress网站不显示菜单高明专业网站建设哪家好