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

网站大学报名官网入口WordPress前端上传大文件

网站大学报名官网入口,WordPress前端上传大文件,建设银行个人网站官网,做网站字体要求目录 1.vector类的介绍 2.vector类常用的接口 2.1 vector类常用构造函数 2.2 vector类常用迭代器 2.3 vector类空间接口 2.4 vector的增删查改 3.vector类的简单实现 3.1 vector类结构以及构造及析构实现 3.2 string类常用接口实现 4.迭代器失效 5.insert的修改 1.ve…

目录

1.vector类的介绍

2.vector类常用的接口

2.1 vector类常用构造函数

2.2 vector类常用迭代器

2.3 vector类空间接口

2.4 vector的增删查改

3.vector类的简单实现

3.1 vector类结构以及构造及析构实现

3.2 string类常用接口实现

4.迭代器失效

5.insert的修改


1.vector类的介绍

vector类代表的是大小可以变化的数组,常见的有,增,删,查,改几个接口(功能),以及vector迭代器的使用。

2.vector类常用的接口

2.1 vector类常用构造函数

构造函数接口说明
vector()无参构造
vector(size_t n,const T& val=T())(注:T代表模版)构造并初始化n个val
vector(const vector<T>& v)拷贝构造
vector (InputIterator first, InputIterator last)
使用迭代器进行初始化构

#include<vector>
#include<iostream>
#include<string>
using namespace std;
int main()
{vector<int> v;//无参构造vector<int> v1(10, 1);//初始化10个1vector<int> v2(v1);//拷贝构造string s;vector<int> v3(s.begin(), s.end());//利用迭代器初始化return 0;
}

vector类使用时一定要实例化

2.2 vector类常用迭代器

iterator的使用接口说明
begin+end
begin获取第一个数据位置的iterator/const_iterator
end获取最后一个数据的下一个位置的iterator/const_iterator
rbegin+rend
begin获取最后一个数据位置的iterator/const_iterator
end获取第一个数据的前一个位置的iterator/const_iterator
#include<vector>
#include<iostream>
using namespace std;
int main()
{vector<int> myvector;//插入数据for (int i = 1; i <= 5; i++) myvector.push_back(i);//正向迭代器for (vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)cout << ' ' << *it;cout << '\n';//反向迭代器for (vector<int>::reverse_iterator it = myvector.rbegin(); it != myvector.rend(); ++it)cout << ' ' << *it;cout << '\n';return 0;
}

2.3 vector类空间接口

容量空间接口说明
size
获取数据个数
capacity
获取容量大小
empty
判断是否为空
resize
改变vectorsize
reserve
改变vectorcapacity

注:vscapacity是按1.5倍增长的,g++是按2倍增长的

reserve(size_t res_arg=0) 预留空间,不改变有效元素个数,当 reserve 的参数小于 string 的底层空间总大小时, reserver 不会改变容量大小。

resize(size_t n) 与 resize(size_t n,T val=T()) 都是将vector有效数据改变到 n 个,不同的是当n>capacity时 resize(n) 用 val来填充多出的元素空间,若没有写val的参数,使用val类型的默认构造的缺省值
注意: resize 在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。

#include<vector>
#include<iostream>
#include<string>
using namespace std;
template<class T>
void Print(const vector<T>& x)
{for (auto e : x){cout << e << " ";}cout << endl;
}
int main()
{vector<int> v(10, 1);cout << v.size() << " " << v.capacity() << " ";Print(v);//打印v.resize(5);//当n小于capacitycout << v.size() << " " << v.capacity() << " ";Print(v);v.resize(15, 2);//当n大于capacity,多的空间用val填入cout << v.size() << " " << v.capacity() << " ";Print(v);v.resize(25);//使用val类型的默认构造的缺省值cout << v.size() << " " << v.capacity() << " ";Print(v);v.reserve(20);//当n小于capacity时,不变cout << v.size() << " " << v.capacity() << " ";Print(v);v.reserve(30);cout << v.size() << " " << v.capacity() << " ";Print(v);return 0;
}

当确定vector存储元素的个数时,可以利用reserve提前开好一定的空间,防止多次扩容

2.4 vector的增删查改

函数名称接口说明
push_back尾插
pop_back()尾删
insert在pos位置前插入数据
erase删除pos位置的数据
swap交换两个vector的存储空间
operator[ ]和数组一样访问
#include<vector>
#include<iostream>
#include<string>
using namespace std;
template<class T>
void Print(const vector<T>& x)
{for (auto e : x){cout << e << " ";}cout << endl;
}
int main()
{vector<int> v;//尾插v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.push_back(5);Print(v);//尾删v.pop_back();v.pop_back();Print(v);//插入v.insert(v.begin()+2, 20);//第一个参数是迭代器类型Print(v);//删除v.erase(v.end()-1);//参数是迭代器类型Print(v);//数组访问v[1] = 10;Print(v);//交换数据vector<int> v1(10, 1);Print(v);Print(v1);v.swap(v1);Print(v);Print(v1);return 0;
}

3.vector类的简单实现

3.1 vector类结构以及构造及析构实现

vector内的数据类型可能是int,double,对于这种不确定是那种类型时,可以利用模版来解决,而vector的结构由三个迭代器组成,而迭代器的底层就是指针

namespace chuxin
{template<class T>class vector{public:typedef const T* const_iterator;typedef T* iterator;private:iterator _start=nullptr;iterator _finish=nullptr;iterator _end_of_storage=nullptr;};
}

对于默认构造,由于此时给了成员变量的缺省值,而且默认构造要走初始化列表,默认构造就不需要写任何内容

对于用迭代器来构造vector,可以利用模版,类模板的成员函数,还可以继续是函数模版

vector()//默认构造
{}
vector(const vector<T>& v)//拷贝构造函数
{reserve(v.size());//开辟空间for (auto e : v){push_back(e);//一个一个数据插入}
}
// 类模板的成员函数,还可以继续是函数模版
//利用迭代器来构造
template <class InputIterator>
vector(InputIterator first, InputIterator last)
{while (first != last){push_back(*first);++first;}
}
//构造并初始化
vector(size_t n, const T& val = T())//T()代表用T类型的默认构造来做缺省值
{reserve(n);for (size_t i = 0; i < n; i++){push_back(val);}
}
~vector()//析构
{if (_start){delete[] _start;_start = _finish = _end_of_storage = nullptr;}
}

3.2 string类常用接口实现

4.2.1 size,capacityt ,operator[ ],clear,begin,end,赋值=

size,capacityt ,operator[ ],clear,begin,end这几个比较简单,不做叙述

	iterator begin()//迭代器{return _start;}iterator end(){return _finish;}const_iterator begin()const{return _start;}const_iterator end()const{return _finish;}size_t size()const{return _finish - _start;}size_t capacity()const{return _end_of_storage - _start;}T& operator[](size_t i){assert(i < size());return _start[i];}const T& operator[](size_t i) const{assert(i < size());return _start[i];}void clear()//清理数据{_finish = _start;}

对于赋值=,可以利用swap交换来使用

void swap(vector<T>& v)
{std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_end_of_storage, v._end_of_storage);
}
vector<T>& operator=(vector<T>& v)//赋值
{swap(v);return *this;
}

3.2.2 reserse(扩容)

对于扩容,这里有一些关于深浅拷贝的问题,来看一下代码

void reserve(size_t n)//扩容
{if (n > capacity()){size_t old_size = _finish - _start;//记录数据iterator tmp = new T[n];memcpy(tmp, _start, old_size * sizeof(T));_start = tmp;_finish = tmp + old_size;_end_of_storage=tmp + n;}
}
memcpy是内存的二进制格式拷贝,将一段内存空间中内容原封不动的拷贝到另外一段内存空间中,如果拷贝的是内置类型的元素,memcpy既高效又不会出错,但如果拷贝的是自定义类型元素,并且自定义类型元素中涉及到资源管理时,就会出错,也就是说,当使用memcap拷贝数据时,_start指向的空间和tmp指向的空间就是同一块地方
void reserve(size_t n)//扩容
{if (n > capacity()){size_t old_size = _finish - _start;//记录数据iterator tmp = new T[n];for (size_t i = 0; i < old_size; i++)//深拷贝{tmp[i] = _start[i];}_start = tmp;_finish = tmp + old_size;_end_of_storage=tmp + n;}
}

3.2.3 empty,pop_back,push_back

bool empty()const
{return _finish == _start;
}
void pop_back()//尾删
{assert(_finish != _start);--_finish;
}
void push_back(const T& x)//尾插
{if (_finish == _end_of_storage){reserve(capacity() == 0 ? 4 : capacity() * 2);}*_finish = x;++_finish;
}

3.2.4 insert

iterator insert(iterator pos, const T& x)
{assert(pos <= _finish);assert(pos >= _start);if (_finish == _end_of_storage){reserve(capacity() == 0 ? 4 : capacity() * 2);}iterator end = _finish - 1;while (pos <= end){*(end + 1) = *end;//移动数据--end;}*pos = x;++_finish;return pos;
}

这里的insert有些问题,下文解释

3.2.5 erase

void erase(iterator pos)
{assert(pos < _finish);assert(pos >= _start);iterator it = pos + 1;while (it != end()){*(it-1) = *it;++it;}--_finish;
}

4.迭代器失效

迭代器失效,实际就是迭代器底层对应指针所指向的空间被销毁了,或者迭代器与预想的作用不同

来看下列代码

void test_vector1()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.push_back(5);Print(v);//打印int x;cin >> x;auto p = find(v.begin(), v.end(), x);if (p != v.end()){v.insert(p, 20);(*p) *= 10;}Print(v);
}

p原本指向的是2,当插入20时,p的指向确变成了插入的数据,此时p的位置没有改变,这就是一个迭代器失效,因此insert以后p就是失效,不要直接访问,要访问就要更新这个失效的迭代器的值

	void test_vector1(){vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.push_back(5);Print(v);int x;cin >> x;auto p = find(v.begin(), v.end(), x);if (p != v.end()){// insert以后p就是失效,不要直接访问,要访问就要更新这个失效的迭代器的值/*v.insert(p, 20);(*p) *= 10;*/p = v.insert(p, 40);(*(p + 1)) *= 10;}Print(v);}
}

同时当插入一个数时,进行了扩容,由于旧空间会被释放,此时的迭代器由于没有更新,变成了野指针,不能直接使用

void test_vector1()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.push_back(4);v.push_back(5);auto it = v.begin();while (it != v.end()){if (*it % 2 == 0)//删除偶数v.erase(it);++it;}prinCon(v);//打印
}

对于这份代码,发现连续的偶数无法删除,当遇到偶数时,删除,此时迭代器失效,没有改变位置,对迭代器++,就会跳过连续的偶数,如果pos刚好是最后一个元素,删完之后pos刚好是end 的位置,而end位置是没有元素的,那么pos同样也失效了,因此可以对迭代器进行更新

void test_vector1()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.push_back(4);v.push_back(5);auto it = v.begin();while (it != v.end()){if (*it % 2 == 0)it = v.erase(it);else++it;}prinCon(v);
}

5.insert的修改

由于知道扩容会对迭代器失效,在某一位置插入数据时,可以记录一下迭代器,避免迭代器失效

iterator insert(iterator pos, const T& x)
{assert(pos <= _finish);assert(pos >= _start);if (_finish == _end_of_storage){size_t len = pos - _start;reserve(capacity() == 0 ? 4 : capacity() * 2);pos = _start + len;//更新迭代器}iterator end = _finish - 1;while (pos <= end){*(end + 1) = *end;//移动数据--end;}*pos = x;++_finish;return pos;
}

http://www.dtcms.com/wzjs/842128.html

相关文章:

  • 网站开发服务合同范本企业文档管理wordpress
  • 《水利建设与管理》杂志社网站大数据分析
  • 毕业设计网站开发选题依据什么网站可以申请做汉语老师
  • 濮阳市建站公司python做网站 框架
  • 赣州网站制作培训wordpress主题集成插件下载
  • 如何在虚拟空间上做多个网站wordpress 网店主题
  • 与网站签约python 做 网站
  • 免费网站建设协议网站设计昆明
  • 广州论坛建站模板建筑网站官网
  • 在线旅游攻略网站建设方案99元一月做网站
  • 怎样用xampp做网站品牌建设属于哪个部门
  • 刚做的网站关键词就上来了10秒折一把古风伞
  • 婚庆网站有哪些做网站的职位叫什么
  • 苏州企业网站公司都有哪些wordpress增加js效果
  • 如何做新闻类网站短视频seo系统
  • 网站的美观性网站建设学生兼职
  • 建站哪个好一点韶关网站推广
  • 中山营销型网站建设网站建设的整个流程图
  • 网站建设西安外贸公司网站大全
  • 做网站能改吗那些平台可以给网站做外链
  • 网站信息内容建设建设pc端网站是什么意思
  • 沈阳做网站客户多吗google中文搜索引擎
  • 网站建设工具品牌有哪些免费建立网站论坛
  • 网站图片加alt山东建设局网站 王局
  • 网站源代码下载软件网页制作背景图片设置
  • 5年网站seo优化公司郑州汉狮做网站好不
  • 南做网站网站做跳转在后天那个文件里做
  • 个人网站备案资料川畅联系 做网站多少钱
  • 建设银陕西省分行网站网站服务器
  • 自己给公司做网站难不难o2o网站开发框架