初始化
跟string一样, vector可以采用下面的形式初始化
// 默认空间, 默认初始化 vector<int> vec; // 开10个空间, 初始化为系统默认 vector<int> vec(10); // 开10个空间, 初始化为1 vector<int> vec(10, 1);
vector可以采用 迭代器区间初始化
👇👇👇
- 采用同类型的迭代器区间
vector<string> vs1; vs1.push_back("hello world"); vector<string> vs2 (vs1.begin(), vs1.end()); for (auto e : vs2) { cout << e << " "; } cout << endl; ***** hello world *****
- 采用不同类型的迭代器区间
vector<char> vc(5, 'b'); vector<int> vs2(vc.begin(), vc.end()); for (auto e : vs2) { cout << e << " "; } cout << endl; ***** 98 98 98 98 98 *****
- 采用数组
int a[5] = { 1,2,3,4,5 }; vector<int> vi (a, a + sizeof(a) / sizeof(int)); for (auto e : vi) { cout << e << " "; } cout << endl; ***** 1 2 3 4 5 *****
排序算法
vector容器本身是没有 sort算法的, 但是算法库
中是有 sort算法的, 头文件是 <algorithm>
👇👇👇
int a[8] = { 11,25,3,14,5, 6, 18,20 }; vector<int> vi (a, a + sizeof(a) / sizeof(int)); sort(vi.begin(), vi.end()); for (auto e : vi) { cout << e << " "; } cout << endl; ***** 3 5 6 11 14 18 20 25 *****
发现, 默认是升序的, 那么如何进行降序呢?
int a[8] = { 11,25,3,14,5, 6, 18,20 }; vector<int> vi (a, a + sizeof(a) / sizeof(int)); greater<int> gt; // greater<int> 仿函数对象 sort(vi.begin(), vi.end(), gt); for (auto e : vi) { cout << e << " "; } cout << endl; ***** 25 20 18 14 11 6 5 3 ***** int a[8] = { 11,25,3,14,5, 6, 18,20 }; vector<int> vi (a, a + sizeof(a) / sizeof(int)); less<int> l; sort(vi.begin(), vi.end(), l); for (auto e : vi) { cout << e << " "; } cout << endl; ***** 3 5 6 11 14 18 20 25 *****
上面的 greater 和 less 是两个仿函数, int 是 模版参数
由于 sort是一个 函数模版 ⇒ 里面的参数是 对象
那么greater 和 less两个仿函数也要传两个对象过去, 即 gt 和 l
⇒ 由此, 我们可以得出: sort函数默认里面放的是less仿函数的对象
由于里面传的是一个对象, 那么匿名对象也是可以的
其实, 我们也可以这样写👇👇👇
int a[8] = { 11,25,3,14,5, 6, 18,20 }; vector<int> vi (a, a + sizeof(a) / sizeof(int)); sort(vi.begin(), vi.end(), greater<int> ()); for (auto e : vi) { cout << e << " "; } cout << endl;
其实, 如果要排降序, 我们也可以抖个机灵
⇒ 反向迭代器
int a[8] = { 11,25,3,14,5, 6, 18,20 }; vector<int> vi (a, a + sizeof(a) / sizeof(int)); sort(vi.rbegin(), vi.rend()); for (auto e : vi) { cout << e << " "; } cout << endl; ***** 25 20 18 14 11 6 5 3 *****
reverse和resize
reverse — — 开空间
resize — — 开空间 + 初始化
基础不好的同学看到这里就有疑问了:
🗨️ reverse 和 resize 的功能重复了, 要一个就可以了! 开空间是最重要的, 那要一个reverse就可以. 初始化啥的, 我们后面自己弄就行了
其实, 这个问题, 我们在 string的模拟实现 中就有答案!
先看下面的一个例子👇👇👇
vector<int> vec; vec.reserve(10); for (int i = 0; i < 10; i++) { vec[i] = i; } ***** error *****
这是因为 operator[] 的实现中, 我们有一个断言 ⇒ assert(i < _size)
这里, 我们开了10个空间 ⇒ _capacity = 10;
但 _size(数据个数) = 0;
⇒ 由于断言, 我们是不能插入数据的
如果要用 []来进行插入数据, 那么我们要用如下的方式👇👇👇
vector<int> vec; vec.resize(10); for (int i = 0; i < 10; i++) { vec[i] = i; }
那我们非要用 reverse
来进行插入数据, 那么我们不应该用 []
, 而是用 push_back
- push_back 和 _size没有关系, 不够了也只是扩容而已
- push_back过后, _size是会进行++的
vector<int> vec; vec.reserve(10); for (int i = 0; i < 10; i++) { vec.push_back(i); }
由此, 我们可以得出: operator[] 是跟 _size 密切相关的 push_back 的使用就比较宽松 并不是开好了空间, 就一定能进行插入数据的