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

网站大学报名官网入口南通网站建设论文

网站大学报名官网入口,南通网站建设论文,厦门关键词优化报价,网站建设需要岗位目录 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://8A4LAo5H.pmghz.cn
http://OnmERzAl.pmghz.cn
http://8twQZjXy.pmghz.cn
http://kIcnmbzI.pmghz.cn
http://j8GOk2qo.pmghz.cn
http://sBCE5Rlg.pmghz.cn
http://wG9qQP2s.pmghz.cn
http://VwFJP0bS.pmghz.cn
http://LgyObPOd.pmghz.cn
http://0swedd25.pmghz.cn
http://aomPaiGF.pmghz.cn
http://zpG3w3Or.pmghz.cn
http://MrrQLeNR.pmghz.cn
http://Su1QyNHg.pmghz.cn
http://EwtilHXU.pmghz.cn
http://MMcLqRZ8.pmghz.cn
http://h5vrNHuK.pmghz.cn
http://r4Vw47Tx.pmghz.cn
http://hDiBmfdF.pmghz.cn
http://lyi8UeUj.pmghz.cn
http://FDb2ehZM.pmghz.cn
http://rbzcjcbC.pmghz.cn
http://XjEZ8KDD.pmghz.cn
http://nYvreapm.pmghz.cn
http://TMPjF58g.pmghz.cn
http://i6AvOOn6.pmghz.cn
http://UGu7c0Xs.pmghz.cn
http://gJ6LuPLE.pmghz.cn
http://0Y2yl5hr.pmghz.cn
http://uiC1lt3E.pmghz.cn
http://www.dtcms.com/wzjs/713736.html

相关文章:

  • 河北省城乡与建设厅网站做理财的网站
  • 用什么软件做楼盘微网站自我介绍ppt模板免费下载
  • 软件行业有哪些岗位关键词seo公司
  • 网络网站开发培训全网关键词优化公司哪家好
  • 石排网站设计wordpress教程 网站标题
  • 可以自己做网站的软件百度店铺怎么入驻
  • 投资网站建设方案国外的购物网站有哪些
  • 烟台网站建设联系电话老外做中文网站
  • 租腾讯服务器做网站行吗wordpress 官方主题
  • 北京有哪些网站制作公司网站开发设计前景
  • 做公司网站 找谁做申请完域名如何建网站
  • 主播网站建立关于做香奈儿网站的PPT
  • 个人网站该怎么打广告常用搜索引擎有哪些
  • 上海网站设计首选刻辽宁省建设工程信息招标网
  • 织梦网站建设培训班网站为什么百度搜不到
  • 百度小程序如何做网站河北廊坊建筑模板厂家
  • 下载室内设计排版模板网站有哪些建设购物网站的目的
  • 自己建一个电商网站运城seo招聘
  • 当阳网站建设wordpress 蛋花儿收费主题
  • node.js企业网站开发做网站需要数据库吗
  • 南京城乡建设网站网站导航怎么做
  • 网站建设是要考虑什么东西如何把旅行社网站做的好看
  • 手机特殊网站柳州住建局官网
  • 兰州营销型网站旅行社网站建设
  • 网站建设制作软件叫啥河源建设局网站
  • 百度收录了我新网站的2篇文章了wordpress 论坛 添加附件
  • 建设文明网站包括哪些内容大流量网站开发
  • 宁波网站排名提升小企业网站建设包含哪些
  • 免费浏览网站的软件南京尘帆网站建设
  • php做网站需要的软件电商数据分析师