C++之vector入门


一、头文件

< v e c t o r > <vector> <vector>和在std中

#include<vector>
using namespace std;

二、结构

其最基本的内存模型是栈结构:先进后出,后进先出。
在这里插入图片描述

三、方法

1.构造

(1)直接赋值

一维容器初始化

vector<int> c1{1,2,3};

二维vector直接赋值

vector<vector<int>> c2{{1,2,3},{4,5,6}};

(2)不带参数的构造函数

vector<int> c1;
//初始化一个空的vector,元素个数size()为0
//之后用push_back(elem)输入元素就行

(3)带参数的构造函数

格式:vector<T> vname(n_size,n_value=0)

//初始化size,但每个元素值为默认值
vector<int> c2(10);		//初始化了10个默认值为0的元素
//初始化size,并且设置初始值
vector<int> c3(10,1);	//初始化了10个值为1的元素

(4)数组转容器

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

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

拷贝构造

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

同数组类似,通过迭代器(begin,end)

vector<int> c1(5, 1);
//通过c的部分1初始化
vector<int> c2(c1.begin(),c1.begin()+3);
//选择了第一二三个。要都选的话,可以直接(c1.begin(),c1.end())

2.总结

常用方法说明
c.pop_back()删除最后一个数据。
c.push_back(elem)在尾部加入一个数据。
c.size()返回容器中实际数据的个数。
c.at(index)传回下标index所指的数据,如果index越界,抛出out_of_range
c.begin()传回迭代器的头一个数据的地址。
c.end()传回迭代器中的最后一个数据的下一位地址。
c.clear()移除容器中所有数据。
c.erase(pos)删除pos位置的数据,传回下一个数据的位置。
pos是迭代器
c.erase(beg,end)删除从beg不到end之间的数据,传回下一个数据的位置。
beg,end是迭代器
c.insert(pos,elem)在pos位置插入一个elem拷贝,传回新数据位置。
pos是迭代器
c.insert(pos,n,elem)在pos位置插入n个elem数据。无返回值。
pos是迭代器
c.insert(pos,beg,end)在pos位置插入在[beg,end)区间的数据。无返回值。
pos、beg、end是迭代器
c.assign(n,elem)赋值操作,类似构造函数一样n个重复的elem
c.assign(begin,end)赋值操作,表示c的所有元素就是另一个容器[begin,end)区间内的元素
不常用方法说明
c1.swap(c2)
swap(c1,c2)
将容器c1和容器c2的元素互换。
c.empty()判断容器是否为空。返回真表示空,反之
c.front()传回第一个数据。
c.back()传回最后一个数据,不检查这个数据是否存在。
c.capacity()返回当前的vector所实际能够容纳的元素的数量。
它应该总是大于或者等于vector的大小size()。
c.clear()清空容器
c.resize(Newsize)保留前Newsize个元素

3.常用方法

(1)c.pop_back()和c.push_back(elem)

vector<double> c;
c.push_back(1);		//里面有一个1
c.pop_back();		//将尾部的1弹出,c空了

(2)c.size()

vector<double> c;
c.push_back(1);
c.push_back(10);
c.push_back(100);
c.push_back(1000);
cout<<c.size()<<endl;
//4

PS:对于vector<T> vname(n),它的size()就是n

vector<int> c(3);
cout << c.size() << endl;
//3

c.push_back(6);
cout << c.size() << endl;
//4
for (int i = 0; i < c.size(); i++)
{
	cout << c[i] << ' ';
}
//0 0 0 6

(3)c.at(index)

vector<double> c;
c.push_back(1);
c.push_back(10);
c.push_back(100);
c.push_back(1000);
cout<<c.at(1)<<endl;
//10

(4)c.begin()

vector<int> c{ 1, 2, 3 };
vector<int>::iterator i = c.begin();
cout << *i << endl;
//1
cout << *(i + 1) << endl;
//2
cout << *(c.begin() + 2) << endl;
//3

(5)c.end()

c.end指向容器的末元素的下一个地址,指向末元素得-1.

vector<int> c{ 1, 2, 3 };
vector<int>::iterator i = c.end();

//c.end()-1才是最后一个数的地址
cout << *(i - 1) << endl;
//3

cout << *(c.end() - 2) << endl;
//2

//直接使用
cout << *(c.end() - 3) << endl;
//1

(6)c.erase(pos)

#include<iostream>
#include<vector>
using namespace std;
int main()
{
	vector<double> c;
	c.push_back(1);
	c.push_back(10);
	c.push_back(100);
	c.push_back(1000);
	
	vector<double>::iterator l=c.begin();
	//l+pos,就是删除下标为pos位置的数据。下标从0开始。
	c.erase(l+1);
	//删除下标为1的元素
	
	for(vector<double>::iterator It=c.begin();It<c.end();It++)
	{
	    cout<<(*It)<<' ';
	}
	//1 100 1000
    return 0;
}

(7)c.erase(beg,end)

从beg不到end之间

#include<iostream>
#include<vector>
using namespace std;
int main()
{
    vector<double> c;
    c.push_back(1);
    c.push_back(10);
    c.push_back(100);
    c.push_back(1000);

    vector<double>::iterator l=c.begin();
    c.erase(l,l+2);
    //删除下标为0、1的元素

    cout<<endl;

    
    for(vector<double>::iterator It=c.begin();It<c.end();It++)
    {
        cout<<(*It)<<' ';
    }
    //100 1000
    return 0;
}

(8)c.insert()

erase()差不多

#include<iostream>
#include<vector>

using namespace std;

int main()
{
    vector<int> v{1,2,3};
    v.insert(v.end(),4);
    for(int i=0;i<v.size();i++)
    {
        cout<<v[i]<<' ';
    }
    //1 2 3 4

    cout<<endl;
    //插入到下标1的位置
    v.insert(v.begin()+1,666);
    for(int i=0;i<v.size();i++)
    {
        cout<<v[i]<<' ';
    }
    //1 666 2 3 4

	/*还可以插入到v.end()处*/
	cout<<endl;
    v.insert(v.end(),5);
    for(int i=0;i<v.size();i++)
    {
        cout<<v[i]<<' ';
    }
    //1 666 2 3 4 5

    cout<<endl;
    v.insert(v.end(),v.begin(),v.end());
    for(int i=0;i<v.size();i++)
    {
        cout<<v[i]<<' ';
    }
    //1 666 2 3 4 5 1 666 2 3 4 5
    return 0;
}

(9)c.assign(n,elem)

注意,c里面原来的元素都被洗掉

vector<int> c{ 1, 2, 3 };
c.assign(5, 10);

for (int i = 0; i < c.size(); i++)
{
	cout << c[i] << ' ';
}
//10 10 10 10 10

(10)c.assign(begin,end)

如将begin到end的值都复制给c。
注意,c里面原来的元素都被洗掉

vector<double> c;
c.push_back(1);
c.push_back(10);
c.push_back(100);
c.push_back(1000);

vector<double> d;

d.assign(c.begin(),c.end());
//c.end()就行,assign()的end是不到end,恰好和c.end()一样,所有直接填

for(int i=0;i<d.size();i++)
{
	cout<<d.at(i)<<endl;
}
//1 10 100 1000

d.assign(c.begin(),c.end());
//d是从头到尾重写,不是接着写

for(int i=0;i<d.size();i++)
{
	cout<<d.at(i)<<endl;
}
//1 10 100 1000

(11)没有find()

4.不常用方法

(1)c1.swap(c2)和swap(c1,c2)

交换两个容器的内容:两个容器的元素数量可以不同,但元素必须一致,否则报错。

vector<double> c;
c.push_back(1);
c.push_back(10);
c.push_back(100);
c.push_back(1000);

vector<double> d;
d.push_back(100);
d.push_back(10);
d.push_back(1);

c.swap(d);

for(int i=0;i<c.size();i++)
{
    cout<<c.at(i)<<' ';
}
//100 10 1

cout<<endl;

for(int i=0;i<d.size();i++)
{
    cout<<d.at(i)<<' ';
}
//1 10 100 1000

(2)c.empty()

vector<int> array;
if (array.empty()) cout << "empty";
//empty

(3)c.front() 和 c.back()

#include <iostream>
#include<vector>
using namespace std;

int main() {
	vector<int> c{1,2,3,4,5};
	cout<<c.front()<<endl;
	//1
	cout<<c.back()<<endl;
	//5
	return 0;
}

(4)c.clear()

#include <iostream>
#include <vector>
using namespace std;
 
int main() {
	vector<int> c{1,2,3,4,5};
	c.clear();
	cout<<c.empty();
	//1,表示空
	return 0;
}

(5)c.resize(Newsize)

#include<iostream>
#include<vector>
using namespace std;
int main()
{
	vector<int> v{ 1,2,3,4,5 };
	v.resize(3);

	for (int i = 0; i < v.size(); i++)
	{
		cout << v[i] << ' ';
	}
	//1 2 3

	return 0;
}

四、for循环输出每个元素

vector<double> c;
c.push_back(1);
c.push_back(10);
c.push_back(100);
c.push_back(1000);

//方式一:c[i]
for(int i=0;i<c.size();i++)
{
    cout<<c[i]<<' ';
}
//1 10 100 1000


//方式二:c.at(pos)
for(int i=0;i<c.size();i++)
{
	cout<<c.at(i)<<' ';
}
//1 10 100 1000


//方式三:迭代器 vector<T>:: iterator It
for(vector<double>::iterator It=c.begin();It<c.end();It++)
{
	cout<<(*It)<<' ';
}
//1 10 100 1000

五、自定义排序

1.自我探索

(1)冒泡排序原型

int a[5]={5,3,2,4,1};
for(int i=5-1;i>0;i--)
{
    for(int j=0;j<i;j++)
    {
        if(a[j]>a[j+1])
        {
            int temp=a[j];
            a[j]=a[j+1];
            a[j+1]=temp;
        }
    }
}

for(int i=0;i<5;i++)
{
    cout<<a[i]<<' ';
}
//1 2 3 4 5

(2)容器冒泡排序

比较简单地使用的话,不会出错。

vector<double> c;
c.push_back(5);
c.push_back(4);
c.push_back(1);
c.push_back(3);
c.push_back(2);

for(vector<double>::iterator i=c.end()-1;i>c.begin();i--)
{
    for(vector<double>::iterator j=c.begin();j<i;j++)
    {
        if((*j)>(*(j+1)))
        {
            c.insert(j+2,j,j+1);
            c.erase(j);
        }
    }
}

for(int i=0;i<5;i++)
{
    cout<<c.at(i)<<' ';
}
//1 2 3 4 5

在这里插入图片描述

但比较复杂的操作时,会出现指针异常:
在这里插入图片描述
在这里插入图片描述
可能是因为容量的问题?

2.简单地使用sort()

用于基本类型的排序,如int。

sort函数没有第三个参数,实现的是从小到大(升序)排列

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
	int a[10] = { 9,6,3,8,5,2,7,4,1,0 };
	for (int i = 0; i < 10; i++)
		cout << a[i] << ' ';
	cout << endl;

	sort(a, a + 10);		//从下标begin不到下标end
	for (int i = 0; i < 10; i++)
		cout << a[i] << ' ';
	cout << endl;
	/*
	9 6 3 8 5 2 7 4 1 0
	0 1 2 3 4 5 6 7 8 9
	*/
	return 0;
}

两种常用的排序方法

  • 升序:sort(begin,end,less());
  • 降序:sort(begin,end,greater()).
sort(a, a + 10, less<int>());		//升序
sort(a, a + 10, greater<int>());	//降序

C++:std::greater()、std::less()、自定义比较函数的规则

3.自定义使用sort()

#include<algorithm>库中sort排序,只用重写排序方式。这种方法出乎意料地简单有效。
而且复杂地操作也有效。

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

//重写排序方法
bool comp(const double &a, const double &b){
//常引用const T &xxx
    return a < b;
    // <代表升序,>代表降序
}

int main()
{
    vector<double> c;
    c.push_back(5);
    c.push_back(4);
    c.push_back(1);
    c.push_back(3);
    c.push_back(2);

	//调用sort()函数
    sort(c.begin(),c.end(),comp);

    for(int i=0;i<5;i++)
    {
        cout<<c.at(i)<<' ';
    }
    //1 2 3 4 5
	return 0;
}

六、实战

去重 unique

C++ 之vector元素去重unique()

反转 reverse

条件

#include <algorithm>
using namespace std;

操作

vector<int> a{1,2,3};
reverse(a.begin(), a.end());	// 从头到尾
reverse(a.begin(), a.end()-1);	// 从头到倒数第二个

八、二维数组

1.构造

格式:vector<vector<int> > c;

注意>和>之间的空格。为了防止有些IDE错误识别为>>运算符

(1)直接赋值

vector<vector<int> > c{ {1,2,3},{4,5,6} };

(2)无参构造的方式

vector<vector<int> > c;

vector<int> r1;
r1.push_back(1);
r1.push_back(2);
r1.push_back(3);
c.push_back(r1);

vector<int> r2;
r2.push_back(4);
r2.push_back(5);
c.push_back(r2);

(3)实现行再实现列

int n = 3, m = 4;	//3行4列
//行
vector<vector<int> > c(n);
//列
for (int i = 0; i < n; i++)
	c[i].resize(m);

(4)同时指定行和列

int n = 3, m = 4;	//3行4列

vector<vector<int> > c(n, vector<int>(m));

2.输出输入

#include <iostream>
#include<queue>
using namespace std;

int main() {
	vector<vector<int> > c;

	vector<int> r1;
	r1.push_back(1);
	r1.push_back(2);
	r1.push_back(3);
	c.push_back(r1);
	
	vector<int> r2;
	r2.push_back(4);
	r2.push_back(5);
	c.push_back(r2);

	//c.size()表示行数
	for (int i = 0; i < c.size(); i++)
	{
		//c[i].size()表示每行各自的元素个数
		for (int j = 0; j < c[i].size(); j++)
		{
			cout << c[i][j] << ' ';
			//cin>>c[i][j];
		}
		cout << endl;
	}
	/*
	1 2 3 
	4 5
	*/
	return 0;
}

参考:
https://blog.csdn.net/xiajun07061225/article/details/7438782#commentBox
https://blog.csdn.net/qq_27736687/article/details/86744072
https://blog.csdn.net/qq_34228570/article/details/79887124

  • 46
    点赞
  • 178
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值