【STL】vector

文章目录

  • 1. vector
  • 2. vector常用接口
    • 2.1 构造函数
    • 2.2 遍历
    • 2.3 增容
    • 2.4 shrink_to_fit
    • 2.5 insert和erase
    • 2.6 find
    • 2.7 sort
  • 3. 练习题
    • 3.1 杨辉三角

1. vector

vector中文意思是向量,它是一个可以改变大小的动态顺序表。
在这里插入图片描述

2. vector常用接口

2.1 构造函数

constructor 接口说明
vector()(重点) 无参构造
vector (const vector& x); (重点) 拷贝构造
vector(size_type n, const value_type& val = value_type()) 构造并初始化n个val
vector (InputIterator first, InputIterator last); 使用迭代器进行初始化构造

vector是一个类模板,它不仅可以存储int、double等类型,还可以存储string,严格来说vector可以存储任意类型。

void test_vector1()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);

	vector<double> v2;
	v2.push_back(1.1);
	v2.push_back(2.2);
	v2.push_back(3.3);

	vector<string> v3;
	//单参数的构造函数支持隐式转换
	//string(const char* str)
	//string s = "hello world";
	//常量字符串构造一个临时对象
	//再拷贝构造给s
	//被优化成直接构造s
	v3.push_back("李白");
	v3.push_back("杜甫");
	v3.push_back("苏轼");
	v3.push_back("白居易");
	
	//10个5初始化
	vector<int> v4(10, 5);
	
	//迭代器区间初始化
	vector<string> v5(++v3.begin(), --v3.end());
	string s = "hello world";
	vector<char> v6(s.begin(), s.end());
}

测试:
【STL】vector_第1张图片

2.2 遍历

void test_vector2()
{
	// 遍历
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);

	// 1、下标+[]
	for (size_t i = 0; i < v.size(); ++i)
	{
		v[i] += 1;
		cout << v[i] << " ";
	}
	cout << endl;

	// 2.迭代器
	vector<int>::iterator it = v.begin();
	while (it != v.end())
	{
		*it -= 1;
		cout << *it << " ";
		++it;
	}
	cout << endl;

	// 3.范围for
	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
}

测试:
【STL】vector_第2张图片

2.3 增容

void test_vector3()
{
	size_t sz;
	vector<int> foo;

	//当前容量
	sz = foo.capacity();
	//增容,容量变了就打印一下
	cout << "making foo grow:\n";
	for (int i = 0; i < 100; ++i) 
	{
		foo.push_back(i);
		if (sz != foo.capacity()) 
		{
			sz = foo.capacity();
			cout << "capacity changed: " << sz << '\n';
		}
	}
}

vs2019下测试:vs(PJ版本STL)下大概是1.5倍的增容
【STL】vector_第3张图片
Linux下:g++(SGI版本STL)是按2倍增长的

g++运行结果:
making foo grow:
capacity changed: 1
capacity changed: 2
capacity changed: 4
capacity changed: 8
capacity changed: 16
capacity changed: 32
capacity changed: 64
capacity changed: 128

单词增容增多少的分析:
单次增容越多,插入N个值,增容次数越少,效率就越高。
单次增容越多,可能浪费就越多。
单次增少了,会导致频繁增容,效率低下,

所以VS、Linux分别选择1.5倍和2倍增容,这也是平衡过的结果。

如果我们已经知道要使用多大的空间,就可以用reserve提前把空间开好(resize会改变size,插入还是会扩容):
【STL】vector_第4张图片

2.4 shrink_to_fit

string、vector都有一个特点:删除数据,一般是不会主动缩容。vector提供shrink_to_fit来请求容器减少容量以适应其大小。
shrink_to_fit的缺点:
(1)如果之后又要插入数据,就又要扩容,那还缩容干嘛!
(2)操作系统不允许内存还一部分,所以缩容的实际操作是先申请一块缩容大小(假设为n个字节)的空间,再把原空间的前n个字节拷贝过来,再释放原空间。

shrink_to_fit付出了性能代价,建议大家慎用。

void test_vector4()
{
	size_t sz;
	vector<int> foo;
	foo.reserve(100);
	foo.resize(10);

	cout << foo.size() << endl;
	cout << foo.capacity() << endl;

	// 慎用、少用
	foo.shrink_to_fit();
	cout << foo.size() << endl;
	cout << foo.capacity() << endl;
}

测试:
【STL】vector_第5张图片

2.5 insert和erase

vector的insert不支持下标,只支持迭代器。

void test_vector5()
{
	// 遍历
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);

	v.insert(v.begin(), -1);
	v.insert(v.begin(), -2);
	v.insert(v.begin(), -3);

	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;

	v.insert(v.begin()+7, 300);
	//v.insert(v.begin()+8, 300);越界,非法的迭代器位置

	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
	v.erase(v.begin());
	v.erase(v.begin());

	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
}

【STL】vector_第6张图片

2.6 find

vector没有查找函数,但是可以复用algorithm库里的find。
【STL】vector_第7张图片

void test_vector6()
{
	// 遍历
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);

	//vector::iterator pos = find(v.begin(), v.end(), 3);
	auto pos = find(v.begin(), v.end(), 3);
	if (pos != v.end())
	{
		cout << "找到了" << endl;
		v.erase(pos);
	}
	else
	{
		cout << "没有找到" << endl;
	}

	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
}

【STL】vector_第8张图片

2.7 sort

【STL】vector_第9张图片

void test_vector7()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(0);
	v.push_back(9);
	v.push_back(3);
	v.push_back(1);

	// 默认是升序
	sort(v.begin(), v.end());
	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;

	// 排降序,仿函数
	// 关于仿函数,大家先记住这个用法,具体我们后面讲队列再详细讲
	sort(v.begin(), v.end(), greater<int>());  // >
	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
}

【STL】vector_第10张图片

3. 练习题

3.1 杨辉三角

杨辉三角
【STL】vector_第11张图片
关于题目给的vector(vector):
【STL】vector_第12张图片
核心思想:找出杨辉三角的规律,发现每一行头尾都是1,中间第[j]个数等于上一行[j-1]+
[j]

class Solution {
public:
    vector<vector<int>> generate(int numRows) {
    vector<vector<int>> vv;
    // 先开辟杨辉三角的空间
    vv.resize(numRows);
    //初始化每一行
    for(size_t i = 0; i < numRows; ++i)
    {
        //每行个数依次递增
        vv[i].resize(i+1, 0);
        // 每一行的第一个和最后一个都是1
        vv[i][0] = 1;
        vv[i][vv[i].size()-1] = 1;
    }
    for(size_t i = 0; i < vv.size(); ++i)
    {
        for(size_t j = 0; j < vv[i].size(); ++j)
        {
            if(vv[i][j] == 0)
            {
                //之间位置等于上一行j-1和j个相加
                vv[i][j] = vv[i-1][j-1] + vv[i-1][j];
            }
        }
    }
    return vv;
    }
};

C语言参考代码:
【STL】vector_第13张图片
【STL】vector_第14张图片

你可能感兴趣的:(c++入门,c++,开发语言)