vector中文意思是向量,它是一个可以改变大小的动态顺序表。
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());
}
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;
}
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倍的增容。
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,插入还是会扩容):
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;
}
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;
}
vector没有查找函数,但是可以复用algorithm库里的find。
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;
}
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;
}
杨辉三角
关于题目给的vector(vector
:
核心思想:找出杨辉三角的规律,发现每一行头尾都是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;
}
};