C++STL中不定长数组vector的底层实现和常用操作

STL其他内容解析:关于C++中STL的理解和应用


目录

vector介绍:

vector的底层实现:

vector初始化:

存取操作:

vector用迭代器访问:

其他操作:

vector作为函数参数传递

vector作为函数返回值

vector的排序

vector在类中使用:

例题:


vector介绍:

vector容器不但能像数组一样对元素进行随机访问,还能在尾部插入元素,是一种简单,高效的容器,完全可以代替数组,vector具有自动管理功能,对于元素的插入和删除,可动态调整所占的内存空间。

vector模版类需要两个模版参数,第一个参数是存储元素的数据类型,第二个参数是存储分配器的类型,其中第二个参数是可选的,如果不给出第二个参数,将使用默认的分配器。

使用要加头文件<vector>。

vector的底层实现

底层是数组,即将元素保存在一段连续的内存空间中。支持快速随机访问。在尾部之外的位置插入删除元素可能会很慢。

PS:当元素已经占满了预先分配的内存空间,插入新的元素时,开辟一段新的内存空间,大小为之前vector的两倍,再将vector内的元素拷贝到新的内存空间内。

vector的插入删除操作会造成迭代器的失效

vector初始化:

(1)不带参数的构造函数初始化

vector<int> a;  //初始化一个size为0的vector

(2)带参数的构造函数初始化

//初始化size,但每个元素值为默认值
vector<int> abc(10);   //初始化了10个默认值为0的元素

//初始化size,并且设置初始值
vector<int> cde(10,1); //初始化了10个值为1的元素

(3)通过数组地址初始化

int a[5] = {1,2,3,4,5}; //通过数组a的地址初始化,注意地址是从0到5(左闭右开区间)
vector<int> b(a, a+5);

(4)通过同类型的vector初始化

vector<int> a(5,1); //通过a初始化
vector<int> b(a);

二维vector的初始化: 

vector<vector<int> > a(n,vector<int>(m,0)); //n行m列的a初始化为0

存取操作:

定义: vector<类型> 变量名称。 如 vector<int> s;

s[i]                    //  直接以下标方式访问容器中的元素
s.front()            //  返回首元素
s.back()            //  返回尾元素
s.push_back(x)      //  向表尾插入元素x
s.pop_back()     //  删除表尾元素
s.size()               //  返回vector大小
s.empty()           //  表为空时,返回真,否则返回假

vector用迭代器访问:

s.begin()            //  返回指向首元素的随机存取迭代器
s.end()              //  返回指向尾元素的下一个位置的随机存取迭代器
s.insert(it, val)     //  向迭代器it指向的元素前插入新元素val
s.insert(it, n, val)  //  向迭代器it指向的元素前插入n个新元素val
s.erase(it)         //  删除由迭代器it所指向的元素   erase函数的返回的是指向被删除元素的下一个元素的迭代器

其他操作:

s.reserve(n)      //缓冲空间,使存储空间至少可容纳n个元素
s.resize(n)         //  改变序列长度,超出的元素将会全部被删除,如果序列需要扩展(原空间小于n),元素默认值将填满扩展出的空间
s.resize(n, val)    //  改变序列长度,超出的元素将会全部被删除,如果序列需要扩展(原空间小于n),val将填满扩展出的空间
s.clear()           //  删除容器中的所有元素
s.swap(v)           //  将s与另一个vector对象进行交换

//  要注意的是,resize操作和clear操作都是对表的有效元素进行的操作,但并不一定会改变缓冲空间的大小
//  另外,vector还有其他的一些操作,如反转、取反等,不再一一列举
//  vector上还定义了序列之间的比较操作运算符(>、<、>=、<=、==、!=),可以按照字典序比较两个序列。

vector作为函数参数传递

  1.  void func(vector<int> x);     传值,需要调用复制构造函数,形参和实参独立的,速度较慢。
  2. void func(vector<int>* x);    传地址,调用时需要用 x-> 形式,形参和实参一致,速度快,但是使用不习惯,所以更习惯用第三种传引用
  3. void func(vector<int>& x);   传引用,形参实参一致,速度快,更方便。如果不想修改实参,可以加const修饰:void func(const vector<int>& x);

vector作为函数返回值

如果返回参数较少,可以不用定义vector,直接用 { } 进行返回。

 vector<int> func(){
    ....
    if () return {l,r}; //返回l,r两个数
        else return {};  //返回空
}

vector的排序

普通的类型

vector<int>v; 

	sort(v.begin(),v.end(),greater<int>());   //从大到小
	sort(v.begin(),v.end(),less<int>());      //从小到大

自定义类型

struct node{
	int a;
	int b;
};
vector<node>v;

bool cmp(node x,node y){
	if(x.a==y.a) return x.b>y.b;
	return x.a>y.a;
}

int main(){
	....
	sort(v.begin(),v.end(),cmp);
	....
 } 

二维vector的排序

如待排序数组为n*2的,按第二个元素的大小排序

    bool cmp(vector<int> a,vector<int> b){
        if (a[1]>b[1]) return true;
        else return false;
    }

    vector<vector<int>> a;
    sort(a.begin(),a.end(),cmp);

自定义排序

sort()函数,默认的是对二维数组按照第一列的大小对每行的数组进行排序。所以可以加上cmp函数用按照任意列对数组进行排序。 

【对二维数组排序】
#include<bits/stdc++.h>
using namespace std;
//按照二维数组第一列的大小对每个一维数组升序排序,
//如何第一列相同时,按照第二列大小对每行的数组降序排序
bool cmp(vector<int>&a,vector<int>&b){
    if(a[0]!=b[0]) return a[0]<b[0];
    else return a[1]>b[1];
}
int main()
{
    vector<vector<int> >a(6);
    int x;
    for(int i=0;i<6;i++){
        for(int j=0;j<2;j++){
            cin>>x;
            a[i].push_back(x);
        }
    }
    cout<<endl;
    sort(a.begin(),a.end(),cmp);
    for(int i=0;i<6;i++){
        for(int j=0;j<2;j++){
            cout<<a[i][j]<<" ";
        }
        cout<<endl;
    }
    return 0;
}

vector在类中使用:

1.vector在类中定义时,不能直接对其实例化。如下是错误的:

class student{
public:
	
private:
	int sum;
	vector<int> score(10);	
};

因为编译器认为,score这个vector不属于student这个类,而是属于实例,所以在这里你想定义score的个数是10,是不行的。

解决办法:在构造函数中,定义vector的大小。如下:

class student{
public:
	student(){
		score=vector<int> (10);
	}
	
private:
	int sum;
	vector<int> score;	
};

2.在类中写cmd函数时,需要声明为static。

因为所有我们在类内定义的非static成员函数在经过编译后隐式的为他们添加了一个this指针参数!变为了:

bool cmp(Solution *this, int a, int b)

而标准库的sort()函数的第三个cmp函数指针参数中并没有这样this指针参数,因此会出现输入的cmp参数和sort()要求的参数不匹配,从而导致了:
error: reference to non-static member function must be called
而我们知道static静态类成员函数是不需要this指针的,因此改为静态成员函数即可通过!

例题:

木块问题:UVa101 木块问题 使用vector求解_马小超-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值