|
(constructor)构造函数声明
|
接口说明
|
|
vector()
|
无参构造
|
|
vector(size_type n, const value_type& val = value_type())
|
构造并初始化n个val
|
|
vector (const vector& x);
|
拷贝构造
|
|
vector (InputIterator first, InputIterator last);
|
使用迭代器进行初始化构造
|
|
iterator的使用
|
接口说明
|
|
begin + end
|
获取第一个数据位置的iterator/const_iterator, 获取最后一个数据的下一个位置 的iterator/const_iterator
|
|
rbegin + rend
|
获取最后一个数据位置的reverse_iterator,获取第一个数据前一个位置的 reverse_iterator
|
|
容量空间
|
接口说明
|
|
size
|
获取数据个数
|
|
capacity
|
获取容量大小
|
|
empty
|
判断是否为空
|
|
resize
|
改变vector的size
|
|
reserve
|
改变vector的capacity
|
|
vector增删查改
|
接口说明
|
|
push_back
|
尾插
|
|
pop_back
|
尾删
|
|
find
|
查找
|
|
insert
|
在position之前插入val
|
|
erase
|
删除position位置的数据
|
|
swap
|
交换两个vector的数据空间
|
|
operator[]
|
像数组一样访问
|
- #include
- using namespace std;
- #include
- int main()
- {
- vector<int> v{ 1,2,3,4,5,6 };
-
- auto it = v.begin();
-
- // 将有效元素个数增加到100个,多出的位置使用8填充,操作期间底层会扩容
- // v.resize(100, 8);
-
- // reserve的作用就是改变扩容大小但不改变有效元素个数,操作期间可能会引起底层容量改变
- // v.reserve(100);
-
- // 插入元素期间,可能会引起扩容,而导致原空间被释放
- // v.insert(v.begin(), 0);
- // v.push_back(8);
-
- // 给vector重新赋值,可能会引起底层容量改变
- v.assign(100, 8);
-
- /*
- 出错原因:以上操作,都有可能会导致vector扩容,也就是说vector底层原理旧空间被释放掉,
- 而在打印时,it还使用的是释放之间的旧空间,在对it迭代器操作时,实际操作的是一块已经被释放的
- 空间,而引起代码运行时崩溃。
- 解决方式:在以上操作完成之后,如果想要继续通过迭代器操作vector中的元素,只需给it重新
- 赋值即可。
- */
- while (it != v.end())
- {
- cout << *it << " ";
- ++it;
- }
- cout << endl;
- return 0;
- }
- #include
- using namespace std;
- #include
- int main()
- {
- int a[] = { 1, 2, 3, 4 };
- vector<int> v(a, a + sizeof(a) / sizeof(int));
- // 使用find查找3所在位置的iterator
- vector<int>::iterator pos = find(v.begin(), v.end(), 3);
- // 删除pos位置的数据,导致pos迭代器失效。
- v.erase(pos);
- cout << *pos << endl; // 此处会导致非法访问
- return 0;
- }
- // 1. 扩容之后,迭代器已经失效了,程序虽然可以运行,但是运行结果已经不对了
- int main()
- {
- vector<int> v{ 1,2,3,4,5 };
- for (size_t i = 0; i < v.size(); ++i)
- cout << v[i] << " ";
- cout << endl;
- auto it = v.begin();
- cout << "扩容之前,vector的容量为: " << v.capacity() << endl;
- // 通过reserve将底层空间设置为100,目的是为了让vector的迭代器失效
- v.reserve(100);
- cout << "扩容之后,vector的容量为: " << v.capacity() << endl;
-
- // 经过上述reserve之后,it迭代器肯定会失效,在vs下程序就直接崩溃了,但是linux下不会
- // 虽然可能运行,但是输出的结果是不对的
- while (it != v.end())
- {
- cout << *it << " ";
- ++it;
- }
- cout << endl;
- return 0;
- }
-
- 程序输出:
- 1 2 3 4 5
- 扩容之前,vector的容量为: 5
- 扩容之后,vector的容量为 : 100
- 0 2 3 4 5 409 1 2 3 4 5
- // 2. erase删除任意位置代码后,linux下迭代器并没有失效
- // 因为空间还是原来的空间,后序元素往前搬移了,it的位置还是有效的
- #include
- #include
- int main()
- {
- vector<int> v{ 1,2,3,4,5 };
- vector<int>::iterator it = find(v.begin(), v.end(), 3);
- v.erase(it);
-
- cout << *it << endl;
- while (it != v.end())
- {
- cout << *it << " ";
- ++it;
- }
- cout << endl;
- return 0;
- }
- 程序可以正常运行,并打印:
- 44 5
-
- // 3: erase删除的迭代器如果是最后一个元素,删除之后it已经超过end
- // 此时迭代器是无效的,++it导致程序崩溃
- int main()
- {
- vector<int> v{ 1,2,3,4,5 };
- // vector
v{1,2,3,4,5,6}; - auto it = v.begin();
- while (it != v.end())
- {
- if (*it % 2 == 0)
- v.erase(it);
- ++it;
- }
- for (auto e : v)
- cout << e << " ";
- cout << endl;
- return 0;
- }
- ========================================================
- // 使用第一组数据时,程序可以运行
- [sly@VM - 0 - 3 - centos 20220114]$ g++ testVector.cpp - std = c++11
- [sly@VM - 0 - 3 - centos 20220114]$ . / a.out
- 1 3 5
- ======================================================== =
- // 使用第二组数据时,程序最终会崩溃
- [sly@VM - 0 - 3 - centos 20220114]$ vim testVector.cpp
- [sly@VM - 0 - 3 - centos 20220114]$ g++ testVector.cpp - std = c++11
- [sly@VM - 0 - 3 - centos 20220114]$ . / a.out
- Segmentation fault
- #include
- void TestString()
- {
- string s("hello");
- auto it = s.begin();
- // 放开之后代码会崩溃,因为resize到20会string会进行扩容
- // 扩容之后,it指向之前旧空间已经被释放了,该迭代器就失效了
- // 后序打印时,再访问it指向的空间程序就会崩溃
- //s.resize(20, '!');
- while (it != s.end())
- {
- cout << *it;
- ++it;
- }
- cout << endl;
- it = s.begin();
- while (it != s.end())
- {
- it = s.erase(it);
- // 按照下面方式写,运行时程序会崩溃,因为erase(it)之后
- // it位置的迭代器就失效了
- // s.erase(it);
- ++it;
- }
- }
迭代器失效解决办法:在使用前,对迭代器重新赋值即可。
1.给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
- class Solution
- {
- public:
- int singleNumber(vector<int>& nums)
- {
- int value = 0;
- for (auto e : v)
- {
- value ^= e;
- }
- return value;
- }
- };
2.给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。在「杨辉三角」中,每个数是它左上方和右上方的数的和。
- // 涉及resize / operator[]
- // 核心思想:找出杨辉三角的规律,发现每一行头尾都是1,中间第[j]个数等于上一行[j-1]+[j]
- class Solution
- {
- public:
- vector
int>> generate(int numRows) - {
- vector
int>> vv(numRows); - for (int i = 0; i < numRows; ++i)
- {
- vv[i].resize(i + 1, 1);
- }
- for (int i = 2; i < numRows; ++i)
- {
- for (int j = 1; j < i; ++j)
- {
- vv[i][j] = vv[i - 1][j] + vv[i - 1][j - 1];
- }
- }
- return vv;
- }
- };
3.给你一个 升序排列 的数组 nums ,请原地删除重复出现的元素,使每个元素只出现一次 ,返回删除后数组的新长度。元素的相对顺序应该保持 一致 。
- class Solution
- {
- public:
- int removeDuplicates(vector<int>& nums)
- {
- int src = 0, dst = 0;
- while (src < nums.size())
- {
- if (nums[src] == nums[dst])
- {
- ++src;
- }
- else
- {
- nums[++dst] = nums[src++];
- }
- }
-
- nums.resize(dst + 1);
-
- return dst + 1;
-
- }
- };
4.给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按任意顺序返回。
- const char* numToStr[10] = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };
-
- class Solution {
- // string numToStr[10] = {"","","abc","def","ghi","jkl","mno","pqrs", "tuv", "wxyz"};
- public:
- void Combine(string digits, int di,
- vector
& retV, string combineStr) - {
- if (di == digits.size())
- {
- retV.push_back(combineStr);
- return;
- }
-
- // 取数字字符映射字符串
- int num = digits[di] - '0';
- string str = numToStr[num];
- for (auto ch : str)
- {
- Combine(digits, di + 1, retV, combineStr + ch);
- }
- }
-
- vector
letterCombinations(string digits) - {
- vector
v; - if (digits.empty())
- return v;
-
- string str;
- Combine(digits, 0, v, str);
-
- return v;
- }
- };