01、文章目录
文章目录
- 01、文章目录
- 02、浅谈Vector
- 03、Vector成员方法表
- 04、浅谈Vector成员方法
- 4.1 构造函数(vector)
- 4.2 运算符(Operators)
- 4.3 assign()函数
- 4.4 at()函数
- 4.5 back()函数与front()函数
- 4.6 begin()函数与end()函数
- 4.7 capacity()函数
- 4.8 clear()函数
- 4.9 empty()函数
- 4.10 erase()函数
- 4.11 get_allocator函数
- 4.12 insert()函数
- 4.13 max_size
- 4.14 size()函数
- 4.15 resize()函数
- 4.16 rbegin()函数与rend()函数
- 4.17 swap()函数
- 4.18 push_back()函数
- 4.19 pop_back()函数
- 05、容器遍历方法(结)
- 06、几种常用的算法
- 07、小结
02、浅谈Vector
Vectors 包含着一系列连续存储的元素,其行为和数组类似。访问Vector中的任意元素或从末尾添加元素都可以在常量级时间复杂度内完成,而查找特定值的元素所处的位置或是在Vector中插入元素则是线性级时间复杂度。
- 常量级时间复杂度:如果一个算法的时间复杂度是O(1)就称为常量级
- 线性级时间复杂度:如果一个算法的时间复杂度是O(n)就称为线性级。
例如:
对于函数f(n),当不管n的大小为多少,f(n)的运行时间均为固定的时间T(n),则称为常量级的。
若对于f(n1),有运行时间为T(n1),但对于n2=Kn1,有运行时间为T(n2) = KT(n1),则称为线性级的。
从整体上来说,时间为常量级的算法的运行时间与输入的数据规模无关,而线性级的运行时间与输入规模呈线性关系。
03、Vector成员方法表
函数(Function) | 描述(Descriptioon) |
---|---|
vector<数据类型> | 构造函数 |
Operators | 对vector进行赋值或比较 |
assign() | 对Vector中的元素赋值 |
at() | 返回指定位置的元素 |
back() | 返回最末一个元素 |
front() | 返回第一个元素 |
begin() | 返回第一个元素的迭代器 |
end() | 返回最末元素的迭代器(译注:实指向最末元素的下一个位置) |
capacity() | 返回vector所能容纳的元素数量(在不重新分配内存的情况下) |
clear() | 清空所有元素 |
empty() | 判断Vector是否为空(返回true时为空) |
erase() | 删除指定元素 |
get_allocator() | 返回vector的内存分配器 |
insert() | 插入元素到Vector中 |
max_size() | 返回Vector所能容纳元素的最大数量(上限) |
pop_back() | 移除最后一个元素 |
push_back() | 在Vector最后添加一个元素 |
rbegin() | 返回Vector尾部的逆迭代器 |
rend() | 返回Vector起始的逆迭代器 |
reserve() | 设置Vector最小的元素容纳数量 |
resize() | 改变Vector元素数量的大小 |
size() | 返回Vector元素数量的大小 |
swap() | 交换两个Vector |
04、浅谈Vector成员方法
4.1 构造函数(vector)
Syntax:
#include <vector> //使用vector必须包含此头文件,后面的方法,我省略,但是写程序不能省略
vector<int> vec; //构造一个int类型vector容器,名字叫vec
//或者
vector<int> vec(10,0); //构造了一个容量为10,初始值都为0的int类型vector容器,
vector<int> b(4,3);
vector<int> a(b); //用容器b整体复制性赋值容器a
vector<int> a(b.begin(),b.begin()+3); //赋值前3个元素
int tmp[7] = {1,2,3,4,5,6,7}; //数组tmp,int类型数组
vector<int> a(tmp,tmp+7); //从数组中的元素给向量vector赋值
C++ Vectors可以使用以下任意一种参数方式构造:
- 无参数 - 构造一个空的vector,
- 数量(num)和值(val) - 构造一个初始放入num个值为val的元素的Vector
- vector(from) - 构造一个与vector from 相同的vector
- 迭代器(start)和迭代器(end) - 构造一个初始值为[start,end)区间元素的Vector(注:半开区间).
4.2 运算符(Operators)
Syntax:
vector<int> v1,v2;
//运算符如下:
v1 == v2
v1 != v2
v1 <= v2
v1 >= v2
v1 < v2
v1 > v2
v[]
C++ Vectors能够使用标准运算符: ==, !=, <=, >=, <, 和 >. 要访问vector中的某特定位置的元素可以使用 [] 操作符.
两个vectors被认为是相等的,如果:
- 它们具有相同的容量
- 所有相同位置的元素相等.
4.3 assign()函数
Syntax:
vector<int> v1;
vector<int> v2(4,7);
//两种方式
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
//此for写法,待会说
for(int i : v1)
{
cout << "v1:" << i << endl; //1,2,3
}
v1.assign(3,9); //将三个9赋值给v1
for(int j : v1)
{
cout << "v1:" << j << endl; //9,9,9
}
v1.assign(v2.begin(),v2.begin()+3);
for(int k : v1)
{
cout << "v1:" << k << endl; //7,7,7
}
assign() 函数要么将区间[start, end)的元素赋到当前vector,或者赋num个值为val的元素到vector中.这个函数将会清除掉为vector赋值以前的内容.
4.4 at()函数
Syntax:
TYPE at( size_type loc );
//at() 函数 返回当前Vector指定位置loc的元素的引用. at() 函数 比 [] 运算符更加安全, 因为它不会让你去访问到Vector内越界的元素.
//例如, 考虑下面的代码:
vector<int> v( 5, 1 );
for( int i = 0; i < 10; i++ )
{
cout << "Element " << i << " is " << v[i] << endl;
}
//这段代码访问了vector末尾以后的元素,这将可能导致很危险的结果.以下的代码将更加安全:
vector<int> v( 5, 1 );
for( int i = 0; i < 10; i++ )
{
cout << "Element " << i << " is " << v.at(i) << endl;
}
取代试图访问内存里非法值的作法,at() 函数能够辨别出访问是否越界并在越界的时候抛出一个异常.
4.5 back()函数与front()函数
Syntax:
TYPE back();
TYPE front();
//back() 函数返回当前vector最末一个元素的引用.
//front()函数返回当前vector起始元素的引用.
//例如:
vector<int> v;
for( int i = 0; i < 5; i++ ) {
v.push_back(i);
}
cout << "v第一个元素是:" << v.front() << endl; //0
cout << "v最后一个元素是:" << v.back() << endl; //4
4.6 begin()函数与end()函数
Syntax:
iterator begin(); //begin()函数返回一个指向当前vector起始元素的迭代器.
iterator end(); //end() 函数返回一个指向当前vector末尾元素的下一位置的迭代器.注意,如果你要访问末尾元素,需要先将此迭代器自减1.
vector<int> v1( 5, 789 );
vector<int>::iterator it;
for( it = v1.begin(); it != v1.end(); it++ ) {
cout << *it << endl;
}
4.7 capacity()函数
Syntax:
size_type capacity(); //返回当前vector在重新进行内存分配以前所能容纳的元素数量.
//例如:
vector<char> vec;
vec.push_back('a');
vec.push_back('b');
vec.push_back('c');
vec.push_back('d');
vec.push_back('e');
vec.push_back('f');
cout << "vec的容量为:" << vec.capacity() << endl; //6
4.8 clear()函数
Syntax:
void clear(); //删除(清空)当前vector中的所有元素.
//例如:
vector<int> v;
v.push_back(1);
v.push_back(2);
for(int i : v)
{
cout << "v:" << i << endl;
}
v.clear();
cout << "打印j" <<endl;
for(int j : v)
{
cout << j << endl; //里面啥都没有
}
cout << "打印完了" <<endl;
4.9 empty()函数
Syntax:
bool empty(); //如果当前vector没有容纳任何元素,则empty()函数返回true,否则返回false.
//例如:
vector<int> vec;
vec.push_back(1);
if(!vec.empty())
{
cout << "vec is't Null" << endl; //有元素,肯定是走这里来
}
cout << "vec is Null" << endl;
//下面逆序打印
vector<int> v;
for( int i = 0; i < 5; i++ ) {
v.push_back(i);
}
while( !v.empty() ) {
cout << v.back() << endl;
v.pop_back();
}
4.10 erase()函数
Syntax:
iterator erase( iterator loc );
iterator erase( iterator start, iterator end );
/*
erase函数要么删作指定位置loc的元素,要么删除区间[start, end)的所有元素.
返回值是指向删除的最后一个元素的下一位置的迭代器.
*/
// 创建一个vector,置入字母表的前十个字符
vector<char> alphaVector;
for( int i=0; i < 10; i++ )
{
alphaVector.push_back( i + 65 );
}
int size = alphaVector.size();
vector<char>::iterator startIterator;
vector<char>::iterator tempIterator;
for( int i=0; i < size; i++ )
{
tartIterator = alphaVector.begin();
alphaVector.erase( startIterator ); // Display the vector
for( tempIterator = alphaVector.begin(); tempIterator != alphaVector.end();tempIterator++)
{
cout << *tempIterator;
}
cout << endl;
}
这段代码将会显示如下输出:
BCDEFGHIJ
CDEFGHIJ
DEFGHIJ
EFGHIJ
FGHIJ
GHIJ
HIJ
IJ
J
4.11 get_allocator函数
Syntax:
allocator_type get_allocator(); //函数返回当前vector的内存分配器.
//这里输出我用printf输出,不然要重载运算符,到时候聊重载运算符再以此为例
vector<int> vec;
for(int i = 0; i < 10; i++)
{
vec.push_back(i+1);
}
printf("内存分配:%d\n",vec.get_allocator()); //204
至于为何是204,大家可以暂时不用管,我也是初学者,用不上的东西先搁一搁。
4.12 insert()函数
Syntax:
iterator insert( iterator loc, const TYPE &val );
void insert( iterator loc, size_type num, const TYPE &val );
void insert( iterator loc, input_iterator start, input_iterator end );
/*
nsert() 函数有以下三种用法:
1、在指定位置loc前插入值为val的元素,返回指向这个元素的迭代器,
2、在指定位置loc前插入num个值为val的元素
3、在指定位置loc前插入区间[start, end)的所有元素 .
*/
//例如:
//创建一个vector,置入字母表的前十个字符
vector<char> alphaVector;
for( int i=0; i < 10; i++ )
alphaVector.push_back( i + 65 );
//插入四个C到vector中
vector<char>::iterator theIterator = alphaVector.begin();
alphaVector.insert( theIterator, 4, 'C' );
//显示vector的内容
for( theIterator = alphaVector.begin(); theIterator != alphaVector.end(); theIterator++ )
cout << *theIterator;
这段代码将显示:
CCCCABCDEFGHIJ
4.13 max_size
Syntax:
size_type max_size(); //返回当前vector所能容纳元素数量的最大值(译注:包括可重新分配内存).
vector<int> v;
for(int i = 0; i < 4; i++)
{
v.push_back(i);
}
cout << v.max_size(); << endl; //1073741823
4.14 size()函数
Syntax:
size_type size(); //返回当前vector所容纳元素的数目
vector<int> v;
for(int i = 0; i < 4; i++)
{
v.push_back(i);
}
cout << v.size(); << endl; //4
4.15 resize()函数
Syntax:
void resize( size_type size, TYPE val ); //改变当前vector的大小为size,且对新创建的元素赋值val
vector<int> v;
for(int i = 0; i < 4; i++)
{
v.push_back(i);
}
cout << v.size() << endl; //4
v.resize(6,9);
cout << v.size() << endl; //6
4.16 rbegin()函数与rend()函数
Syntax:
reverse_iterator rbegin(); //返回指向当前vector末尾的逆迭代器.(译注:实际指向末尾的下一位置,而其内容为末尾元素的值)
reverse_iterator rend(); //返回指向当前vector起始位置的逆迭代器.
与begin()函数与end()函数作用相反,所以这里不举例了。
4.17 swap()函数
Syntax:
void swap( vector &from ); //swap()函数交换当前vector与vector from的元素
//如下所示:
vector<int> v;
for(int i = 0; i < 3; i++)
{
v.push_back(i);
}
cout << "交换前:" <<endl;
for(int i : v)
{
cout << i << " "; //0 1 2
}
cout<<endl;
vector<int> v1;
for(int i = 0; i < 3; i++)
{
v1.push_back(i+3);
}
v.swap(v1);
cout << "交换后:" << endl;
for(int i : v)
{
v.push_back(i); //3 4 5
}
4.18 push_back()函数
Syntax:
//这个函数从开始就一直在写,应该知道怎么用了吧
void push_back( const TYPE &val ); //添加值为val的元素到当前vector末尾
注意这里的值一定要和vector<数据类型>中的数据类型匹配
4.19 pop_back()函数
Syntax:
void pop_back(); //函数删除当前vector最末的一个元素,例如:
vector<char> alphaVector;
for( int i=0; i < 10; i++ )
{
alphaVector.push_back( i + 65 );
}
int size = alphaVector.size();
vector<char>::iterator startIterator;
vector<char>::iterator tempIterator;
for( int i=0; i < size; i++ )
{
tartIterator = alphaVector.begin();
alphaVector.erase( startIterator ); // Display the vector
for( tempIterator = alphaVector.begin(); tempIterator != alphaVector.end();tempIterator++)
{
cout << *tempIterator;
}
cout << endl;
}
这段代码将显示以下输出:
ABCDEFGHI
ABCDEFGH
ABCDEFG
ABCDEF
ABCDE
ABCD
ABC
AB
A
到此,关于STL——vector的所有函数都说完了。然后现在聊聊上一节string说的要提及的遍历方法。
05、容器遍历方法(结)
容器遍历方法,我这里总结了三种,两种普遍的,一种就是上面我经常使用的C++ 11中加入的区间迭代!
5.1 下标遍历法
此方法,应该是我们最熟悉的,从C语言学习数组开始就一直在用。
#include <iostream>
#include <vector> //vector头文件
using namespace std;
void Traverse(vector<int> &from)
{
int len = from.size(); //获得vector当前元素个数
for(int i = 0; i < len; i++)
{
cout << from[i] << endl;
}
}
int main()
{
vector<int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
vec.push_back(4);
vec.push_back(5);
vec.push_back(6);
Traverse(vec);
system("pause");
return 0;
}
5.2 迭代器遍历
这种方法,如果你看过我正则的内容,应该知道是啥。如果没有,现在一起来看看,我尽量说的详细点。
#include <iostream>
#include <vector> //vector头文件
using namespace std;
void Traverse(vector<int> &from)
{
/*
迭代器遍历是最原始的一种遍历方式,是底层提供给我们直接用的,而其他遍历方式,就是在迭代器上穿了一件衣服,可以这么理解哈。
*/
vector<int>::iterator start = from.begin(); //获取开始迭代器
vector<int>::iterator end = from.end(); //获取结束迭代器
//开始遍历
for(vector<int>::iterator it = start; it != end; it++)
{
cout << *it << endl;
}
}
int main()
{
vector<int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
vec.push_back(4);
vec.push_back(5);
vec.push_back(6);
Traverse(vec);
system("pause");
return 0;
}
5.3 区间迭代(C++ 11新特性)
这种方法就是非常好用的,适合懒人用的遍历方法。 感觉C++ 11的那些新特性就是为懒而准备的便利方法.
#include <iostream>
#include <vector> //vector头文件
using namespace std;
void Traverse(vector<int> &from)
{
//迭代遍历,一个一个录入到i
for(int i : from)
{
cout << i << endl;
}
}
int main()
{
vector<int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
vec.push_back(4);
vec.push_back(5);
vec.push_back(6);
Traverse(vec);
system("pause");
return 0;
}
06、几种常用的算法
这里介绍几种常见的算法:排列(排序)、复制(拷贝)和替换、查找,算术生成、集合
下面介绍的算法有些需要包含头文件:algorithm
这里只做介绍,后面单独聊此处提及的算法.
6.1 排序算法
- merge算法:容器元素合并,并存储到另一容器中
merge(iterator beg1, iterator end1, iterator beg2, iterator end2,iterator dest);
/*
@param beg1 容器1开始迭代器
@param end1 容器1结束迭代器
@param beg2 容器2开始迭代器
@param end2 容器2结束迭代器
@param dest 目标容器开始迭代器
*/
- sort算法:容器元素排序(两个容器必须是有序的)
sort(iterator beg,iterator end, _callback);
/*
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param _callback 回调函数或者谓词(返回bool类型的函数对象)
*/
- reverse算法:反转指定范围的元素
reverse(iterator beg, iterator end);
/*
@param beg 容器开始迭代器
@param end 容器结束迭代器
*/
6.2 拷贝和替换算法
- copy算法:将容器内指定范围的元素拷贝到另一容器中
copy(iterator beg, iterator end, iterator dest);
/*
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param dest 目标容器结束迭代器
*/
- replace算法:将容器内指定范围的旧元素修改为新元素
replace(iterator begg, iterator end,oldvalue, newvalue);
/*
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param oldvalue 旧元素
@param newvalue 新元素
*/
- replace_if算法:将容器内指定范围满足条件的元素替换为新元素
replace_if(iterator beg, iterator end, _callback, newvalue)
/*
@param beg 容器开始迭代器
@param end 容器结束迭代器
@_callback 回调函数或者谓词(返回bool类型的函数对象)
@param newvalue 新元素
*/
- swap算法:互换两个容器的元素
swap(container c1, coontainer c2);
/*
@param c1 容器1
@param c2 容器2
*/
6.3 查找算法
find(a.begin(),a.end(),10); //在a中的从a.begin()(包括它)到a.end()(不包括它)的元素中查找10,若存在返回其在向量中的位置
- find算法:查找容器中的元素是否匹配要要找的元素
find(itreator start, itreator end, Type target);
/*
@param start 容器开始迭代器
@param end 容器结束迭代器
@param target 容器对应类型的值(要查找的值)
*/
6.4 算术生成算法
- accumulate算法:计算容器元素累计总和
accumulate(iterator beg, iterator end, value t);
/*
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value t 累加值
*/
- fill算法:向容器中添加元素
fill(iterator beg, iterator end, value t);
/*
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value t 填充元素
*/
6.5 集合算法
- set_intersection算法:求两个set集合的交集
//注意:两个集合必须是有序序列
set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2 iterator dest);
/*
@param beg1 容器1开始迭代器
@param end1 容器1结束迭代器
@param beg2 容器2开始迭代器
@param end2 容器2结束迭代器
@param dest 目标容器开始迭代器
@return 目标容器的最后一个元素的迭代器地址
*/
- set_union算法:求两个set集合的并集
//注意:两个集合必须是有序序列
set_union(iterator beg1, iterator end1, iterator beg2, iterator end2 iterator dest);
/*
@param beg1 容器1开始迭代器
@param end1 容器1结束迭代器
@param beg2 容器2开始迭代器
@param end2 容器2结束迭代器
@param dest 目标容器开始迭代器
@return 目标容器的最后一个元素的迭代器地址
*/
- set_difference算法:求两个set集合的差集
//注意:两个集合必须是有序序列
set_union(iterator beg1, iterator end1, iterator beg2, iterator end2 iterator dest);
/*
@param beg1 容器1开始迭代器
@param end1 容器1结束迭代器
@param beg2 容器2开始迭代器
@param end2 容器2结束迭代器
@param dest 目标容器开始迭代器
@return 目标容器的最后一个元素的迭代器地址
*/
07、小结
vector容器是STL 中非常重要的容器,一定要掌握。
这里贴一个张表:
C/C++ | STL | 对应关系 |
---|---|---|
数组 | vector容器 | 类似等同关系,数据结构一样 |
链表 | list容器 | 类似等同关系,数据结构一样 |
算法,我们就聊完list、set等容器之后再做一个总回顾吧,暂且放一放!
如果博主有什么地方不正确,请大家指出一下,谢谢。
版权声明:转载请注明出处,谢谢!