• <vector模拟实现>——《C++初阶》


    目录

    1.vector深度剖析及模拟实现:

    1.1 std::vector的核心框架接口的模拟实现bit::vector 

    1.2 使用memcpy拷贝问题

    1.3 对bit::vector核心接口的测试

    1.4动态二维数组理解

    2.vector模拟实现源码: 

    2.1:完整源码:

    2.2例题:使用vector实现杨辉三角:​

    后记:●由于作者水平有限,文章难免存在谬误之处,敬请读者斧正,俚语成篇,恳望指教!                                                                  ——By 作者:新晓·故知


    1.vector深度剖析及模拟实现:

    vector的模拟实现主要对常用的函数接口:构造函数、拷贝构造函数、析构函数、赋值重载函数、vector迭代器、reserve、push_back、pop_back、insert、resize、erase等。

    对vector在Linux环境下g++编译器与Windows环境下VS系列编译器的vector迭代器失效问题进行对比、解决。

     

    1.1 std::vector的核心框架接口的模拟实现bit::vector 

    1. #include
    2. using namespace std;
    3. #include
    4. //自定义命名空间,防止与库冲突
    5. namespace bit
    6. {
    7. template<class T>
    8. class vector
    9. {
    10. public:
    11. // Vector的迭代器是一个原生指针
    12. typedef T* iterator;
    13. typedef const T* const_iterator;
    14. iterator begin() { return _start; }
    15. iterator end() { return _finish; }
    16. const_iterator cbegin() const { return _start; }
    17. const_iterator cend() const { return _finish; }
    18. // construct and destroy
    19. vector()
    20. : _start(nullptr)
    21. , _finish(nullptr)
    22. , _endOfStorage(nullptr)
    23. {}
    24. vector(int n, const T& value = T())
    25. : _start(nullptr)
    26. , _finish(nullptr)
    27. , _endOfStorage(nullptr)
    28. {
    29. reserve(n);
    30. while (n--)
    31. {
    32. push_back(value);
    33. }
    34. }
    35. // 若使用iterator做迭代器,会导致初始化的迭代器区间[first,last)只能是vector的迭代器
    36. // 重新声明迭代器,迭代器区间[first,last)可以是任意容器的迭代器
    37. template<class InputIterator>
    38. vector(InputIterator first, InputIterator last)
    39. {
    40. reserve(last - first);
    41. while (first != last)
    42. {
    43. push_back(*first);
    44. ++first;
    45. }
    46. }
    47. vector(const vector& v)
    48. : _start(nullptr)
    49. , _finish(nullptr)
    50. , _endOfStorage(nullptr)
    51. {
    52. reserve(v.capacity());
    53. iterator it = begin();
    54. const_iterator vit = v.cbegin();
    55. while (vit != v.cend())
    56. {
    57. *it++ = *vit++;
    58. }
    59. }
    60. vector& operator=(vector v)
    61. {
    62. swap(v);
    63. return *this;
    64. }
    65. ~vector()
    66. {
    67. delete[] _start;
    68. _start = _finish = _endOfStorage = nullptr;
    69. }
    70. // capacity
    71. size_t size() const { return _finish - _start; }
    72. size_t capacity() const { return _endOfStorage - _start; }
    73. bool empty() const { return _first == _finish; }
    74. void reserve(size_t n)
    75. {
    76. if (n > capacity())
    77. {
    78. size_t oldSize = size();
    79. T* tmp = new T[n];
    80. // 这里直接使用memcpy?
    81. //if (_start)
    82. // memcpy(tmp, _start, sizeof(T)*size);
    83. if (_start)
    84. {
    85. for (size_t i = 0; i < oldSize; ++i)
    86. tmp[i] = _start[i];
    87. }
    88. _start = tmp;
    89. _finish = _start + oldSize;
    90. _endOfStorage = _start + n;
    91. }
    92. }
    93. void resize(size_t n, const T& value = T())
    94. {
    95. // 1.如果n小于当前的size,则数据个数缩小到n
    96. if (n <= size())
    97. {
    98. _finish = _start + n;
    99. return;
    100. }
    101. // 2.空间不够则增容
    102. if (n > capacity())
    103. reserve(n);
    104. // 3.将size扩大到n
    105. iterator it = _finish;
    106. _finish = _start + n;
    107. while (it != _finish)
    108. {
    109. *it = value;
    110. ++it;
    111. }
    112. }
    113. ///access///
    114. T& operator[](size_t pos) { return _start[pos]; }
    115. const T& operator[](size_t pos)const { return _start[pos]; }
    116. ///modify/
    117. void push_back(const T& x) { insert(end(), x); }
    118. void pop_back() { erase(--end()); }
    119. void swap(vector& v)
    120. {
    121. std::swap(_start, v._start);
    122. std::swap(_finish, v._finish);
    123. std::swap(_endOfStorage, v._endOfStorage);
    124. }
    125. iterator insert(iterator pos, const T& x)
    126. {
    127. assert(pos <= _finish);
    128. // 空间不够先进行增容
    129. if (_finish == _endOfStorage)
    130. {
    131. //size_t size = size();
    132. size_t newCapacity = (0 == capacity()) ? 1 : capacity() * 2;
    133. reserve(newCapacity);
    134. // 如果发生了增容,需要重置pos
    135. pos = _start + size();
    136. }
    137. iterator end = _finish - 1;
    138. while (end >= pos)
    139. {
    140. *(end + 1) = *end;
    141. --end;
    142. }
    143. *pos = x;
    144. ++_finish;
    145. return pos;
    146. }
    147. // 返回删除数据的下一个数据
    148. // 方便解决:一边遍历一边删除的迭代器失效问题
    149. iterator erase(iterator pos)
    150. {
    151. // 挪动数据进行删除
    152. iterator begin = pos + 1;
    153. while (begin != _finish) {
    154. *(begin - 1) = *begin;
    155. ++begin;
    156. }
    157. --_finish;
    158. return pos;
    159. }
    160. private:
    161. iterator _start; // 指向数据块的开始
    162. iterator _finish; // 指向有效数据的尾
    163. iterator _endOfStorage; // 指向存储容量的尾
    164. };
    165. }

    1.2 使用memcpy拷贝问题

    假设模拟实现的vector中的reserve接口中,使用memcpy进行的拷贝,以下代码会发生什么问题?
    1. int main()
    2. {
    3. bite::vector v;
    4. v.push_back("1111");
    5. v.push_back("2222");
    6. v.push_back("3333");
    7. return 0;
    8. }

     
    问题分析:
    1. memcpy是内存的二进制格式拷贝,将一段内存空间中内容原封不动的拷贝到另外一段内存空间中
    2. 如果拷贝的是自定义类型的元素,memcpy即高效又不会出错,但如果拷贝的是自定义类型元素,并且自定义类型元素中涉及到资源管理时,就会出错,因为memcpy的拷贝实际是浅拷贝。

    结论:如果对象中涉及到资源管理时,千万不能使用memcpy进行对象之间的拷贝,因为memcpy是浅拷贝,否则可能会引起内存泄漏甚至程序崩溃。

     1.3 bit::vector核心接口的测试

    1. // constructing vectors
    2. void TestVector1()
    3. {
    4. // constructors used in the same order as described above:
    5. bite::vector<int> first; // empty vector of
    6. ints
    7. bite::vector<int> second(4, 100); // four ints with value
    8. 100
    9. bite::vector<int> third(second.Begin(), second.End()); // iterating through
    10. second
    11. bite::vector<int> fourth(third); // a copy of third
    12. // the iterator constructor can also be used to construct from arrays:
    13. int myints[] = { 16, 2, 77, 29 };
    14. bit::vector<int> fifth(myints, myints + sizeof(myints) / sizeof(int));
    15. std::cout << "The contents of fifth are:";
    16. for (bit::vector<int>::iterator it = fifth.begin(); it != fifth.end(); ++it)
    17. std::cout << *it << " ";
    18. std::cout << endl;
    19. // 测试T是string时,拷贝问题
    20. bit::vector strV;
    21. strV.PushBack("1111");
    22. strV.PushBack("2222");
    23. strV.PushBack("3333");
    24. strV.PushBack("4444");
    25. for (size_t i = 0; i < strV.size(); ++i)
    26. {
    27. cout << strV[i] << " ";
    28. }
    29. cout << endl;
    30. }
    31. //vector iterator的使用
    32. void PrintVector(const bite::vector<int>& v) {
    33. // 使用const迭代器进行遍历打印
    34. bit::vector<int>::const_iterator it = v.begin();
    35. while (it != v.end())
    36. {
    37. cout << *it << " ";
    38. ++it;
    39. }
    40. cout << endl;
    41. }
    42. void TestVector2()
    43. {
    44. // 使用push_back插入4个数据
    45. bite::vector<int> v;
    46. v.push_back(1);
    47. v.push_back(2);
    48. v.push_back(3);
    49. v.push_back(4);
    50. PrintVector(v);
    51. // 使用迭代器进行修改
    52. auto it = v.begin();
    53. while (it != v.end())
    54. {
    55. *it *= 2;
    56. ++it;
    57. }
    58. PrintVector(v);
    59. // 这里可以看出C++11支持iterator及接口,就支持范围for
    60. for (auto e : v)
    61. cout << e << " ";
    62. }
    63. // find / insert / erase
    64. void TestVector3()
    65. {
    66. int a[] = { 1, 2, 3, 4 };
    67. bite::vector<int> v(a, a + sizeof(a) / sizeof(a[0]));
    68. // 使用find查找3所在位置的iterator
    69. auto pos = find(v.begin(), v.end(), 3);
    70. // 在pos位置之前插入30
    71. v.insert(pos, 30);
    72. PrintVector(v);
    73. // 删除pos位置的数据
    74. pos = find(v.begin(), v.end(), 3);
    75. v.Erase(pos);
    76. PrintVector(v);
    77. }
    78. // iterator失效问题
    79. void TestVector4()
    80. {
    81. int a[] = { 1, 2, 3, 4 };
    82. bite::vector<int> v(a, a + sizeof(a) / sizeof(a[0]));
    83. // 删除pos位置的数据,导致pos迭代器失效
    84. auto pos = find(v.begin(), v.end(), 3);
    85. v.erase(pos);
    86. cout << *pos << endl; // 此处会导致非法访问
    87. // 在pos位置插入数据,导致pos迭代器失效。
    88. // insert会导致迭代器失效,是因为insert可
    89. // 能会导致增容,增容后pos还指向原来的空间,而原来的空间已经释放了。
    90. pos = find(v.begin(), v.end(), 3);
    91. v.insert(pos, 30);
    92. cout << *pos << endl; // 此处会导致非法访问
    93. // 实现删除v中的所有偶数
    94. // 下面的程序会崩溃掉,如果是偶数,erase导致it失效
    95. // 对失效的迭代器进行++it,会导致程序崩溃
    96. auto it = v.begin();
    97. while (it != v.end())
    98. {
    99. if (*it % 2 == 0)
    100. v.erase(it);
    101. ++it;
    102. }
    103. // 以上程序要改成下面这样,erase会返回删除位置的下一个位置
    104. it = v.begin();
    105. while (it != v.end())
    106. {
    107. if (*it % 2 == 0)
    108. it = v.erase(it);
    109. else
    110. ++it;
    111. }
    112. }

    注:一般vector删除数据,都不考虑缩容的方案。

    缩容方案:size()

    string迭代器也有失效问题,但string不常使用迭代器,而多使用下标+[ ],vector多使用迭代器,要注意失效问题。

    1.4动态二维数组理解

     
    1. // 以杨辉三角的前n行为例:假设n为5
    2. void test5(size_t n)
    3. {
    4. // 使用vector定义二维数组vv,vv中的每个元素都是vector
    5. bit::vectorint>> vv(n);
    6. // 将二维数组每一行中的vecotr中的元素全部设置为1
    7. for (size_t i = 0; i < n; ++i)
    8. vv[i].resize(i + 1, 1);
    9. // 给杨辉三角出第一列和对角线的所有元素赋值
    10. for (int i = 2; i < n; ++i)
    11. {
    12. for (int j = 1; j < i; ++j)
    13. {
    14. vv[i][j] = vv[i - 1][j] + vv[i - 1][j - 1];
    15. }
    16. }
    17. }

    bit::vector> vv(n); 构造一个vv动态二维数组,vv中总共有n个元素,每个元素都是vector类型的,每行没有包含任何元素,如果n为5时如下所示:

     


    2.vector模拟实现源码: 

    2.1:完整源码:

    (1)vector.h:​​​​​​​

    1. #pragma once
    2. //模拟实现vector
    3. #include
    4. #include
    5. #include
    6. #include
    7. using namespace std;
    8. //自定义命名空间,防止与库里的冲突
    9. namespace my
    10. {
    11. template<class T>
    12. class vector
    13. {
    14. public:
    15. typedef T* iterator;
    16. typedef const T* const_iterator;
    17. //构造函数
    18. vector()
    19. :_start(nullptr)
    20. ,_finish(nullptr)
    21. ,_endofstorage(nullptr)
    22. {}
    23. //使用n个val构造函数
    24. vector(size_t n, const T& val = T())
    25. :_start(nullptr)
    26. , _finish(nullptr)
    27. , _endofstorage(nullptr)
    28. {
    29. reserve(n);
    30. for (size_t i = 0; i < n; ++i)
    31. {
    32. push_back(val);
    33. }
    34. }
    35. vector(int n, const T& val = T())
    36. :_start(nullptr)
    37. , _finish(nullptr)
    38. , _endofstorage(nullptr)
    39. {
    40. reserve(n);
    41. for (size_t i = 0; i < n; ++i)
    42. {
    43. push_back(val);
    44. }
    45. }
    46. //类模板,类构造
    47. template<class InputIterator>
    48. vector(InputIterator first, InputIterator last)
    49. : _start(nullptr)
    50. , _finish(nullptr)
    51. , _endofstorage(nullptr)
    52. {
    53. while (first != last)
    54. {
    55. push_back(*first);
    56. ++first;
    57. }
    58. }
    59. void swap(vector& v)
    60. {
    61. std::swap(_start, v._start);
    62. std::swap(_finish, v._finish);
    63. std::swap(_endofstorage, v._endofstorage);
    64. }
    65. //拷贝构造函数(使用现代写法)
    66. vector(const vector& v)
    67. : _start(nullptr)
    68. , _finish(nullptr)
    69. , _endofstorage(nullptr)
    70. {
    71. vector tmp(v.begin(), v.end());
    72. swap(tmp); //this->swap(tmp);
    73. }
    74. //赋值重载函数(现代写法)
    75. vector& operator=(vector v)
    76. {
    77. swap(v); //this->swap(v);
    78. return *this;
    79. }
    80. //析构函数(资源管理)
    81. ~vector()
    82. {
    83. if (_start)
    84. {
    85. delete[] _start;
    86. _start = _finish = _endofstorage = nullptr;
    87. }
    88. }
    89. iterator begin()
    90. {
    91. return _start;
    92. }
    93. iterator end()
    94. {
    95. return _finish;
    96. }
    97. const_iterator begin() const
    98. {
    99. return _start;
    100. }
    101. const_iterator end() const
    102. {
    103. return _finish;
    104. }
    105. size_t size() const
    106. {
    107. return _finish - _start;
    108. }
    109. size_t capacity() const
    110. {
    111. return _endofstorage - _start;
    112. }
    113. void reserve(size_t n)
    114. {
    115. size_t sz = size();
    116. if (n > capacity())
    117. {
    118. T* tmp = new T[n];
    119. if (_start)
    120. {
    121. //memcpy(tmp, _start, size() * sizeof(T)); //浅拷贝问题
    122. for (size_t i = 0;i < size(); ++i)
    123. {
    124. tmp[i] = _start[i];
    125. }
    126. delete[] _start;
    127. }
    128. _start = tmp;
    129. }
    130. _finish = _start + sz;
    131. _endofstorage = _start + n;
    132. }
    133. //总结:vector中,当T涉及深拷贝的类型时,如:string、vector等等,
    134. //扩容使用memcpy拷贝数据会存在浅拷贝问题,造成析构两次
    135. //解决:使用传值拷贝,如上
    136. void push_back(const T& x)
    137. {
    138. /*if (_finish == _endofstorage)
    139. {
    140. size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;
    141. reserve(newCapacity);
    142. }
    143. *_finish = x;
    144. ++_finish;*/
    145. //附用insert
    146. insert(end(),x);
    147. }
    148. void pop_back()
    149. {
    150. /*if (_finish > _start)
    151. {
    152. --_finish;
    153. }*/
    154. //附用erase
    155. erase(end()-1);
    156. }
    157. T& operator[](size_t pos)
    158. {
    159. assert(pos < size());
    160. return _start[pos];
    161. }
    162. const T& operator[](size_t pos) const
    163. {
    164. assert(pos < size());
    165. return _start[pos];
    166. }
    167. //写在类里的小函数,被当做内联函数处理,减少了多次调用建立栈帧
    168. //void resize(size_t n, const T& val = T())
    169. void resize(size_t n, T val = T()) //T()匿名对象,调用默认构造函数,若T()为int(内置类型),
    170. { //C++对于内置类型也可以认为有构造函数、析构函数,才能支持模板,只是int为0,double为0.1
    171. /*int i = 0;
    172. int j = int();
    173. int k = int(1);*/
    174. if (n > capacity())
    175. {
    176. reserve(n);
    177. }
    178. if (n > size())
    179. {
    180. while (_finish < _start + n)
    181. {
    182. *_finish = val;
    183. ++_finish;
    184. }
    185. }
    186. else
    187. {
    188. _finish = _start + n;
    189. }
    190. }
    191. iterator insert(iterator pos, const T& x) //返回值为iterator,解决迭代器失效问题
    192. {
    193. //如果pos传引用,但有些时候,传不过去
    194. //检查参数
    195. assert(pos >= _start && pos <= _finish);
    196. //扩容
    197. //扩容以后,pos就失效了,要更新
    198. //insert导致的迭代器失效,是因为pos没更新
    199. if (_finish == _endofstorage)
    200. {
    201. size_t n = pos - _start;
    202. size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;
    203. reserve(newCapacity);
    204. pos = _start + n;
    205. }
    206. //挪动数据
    207. iterator end = _finish - 1;
    208. while (end >= pos)
    209. {
    210. *(end + 1) = *end;
    211. --end;
    212. }
    213. *pos = x;
    214. ++_finish;
    215. return pos;
    216. }
    217. //总结:迭代器在insert里的两种失效:
    218. //1.pos失效 2.迭代器it失效
    219. iterator erase(iterator pos)
    220. {
    221. assert(pos >= _start && pos <= _finish);
    222. iterator it = pos + 1;
    223. while (it != _finish)
    224. {
    225. *(it - 1) = *it;
    226. ++it;
    227. }
    228. --_finish;
    229. return pos;
    230. }
    231. //总结:
    232. //1.erase的失效都是意义变了,过着不在有效访问数据有效范围
    233. //2.一般不会使用缩容的方案,那么erase的失效也不存在野指针的失效
    234. //在VS和Linux不同环境下,处理不同
    235. //erase(pos),使得pos失效,pos的意义改变,但是不同环境平台的处理不一样
    236. //在使用的时候,统一以失效的角度看待
    237. //整体总结:
    238. //对于insert和erase造成的迭代器失效问题,Linux环境下g++检查不严格,基本依靠操作系统自身野指针越界检查机制
    239. //Windows环境下,VS系列检查严格,使用一些强制检查机制,意义改变造成的失效,也可能会检查出来
    240. //vector迭代器的失效有两种:
    241. //1.扩容、缩容,导致形成野指针失效
    242. //2.迭代器指向的位置意义改变
    243. //这些通过操作系统的越界检查机制不一定能检查到
    244. //而通过编译器实现机制检查,相对靠谱
    245. void clear()
    246. {
    247. _finish = _start;
    248. }
    249. private:
    250. iterator _start;
    251. iterator _finish;
    252. iterator _endofstorage;
    253. };
    254. }

    (2)test.cpp:

    1. #include "vector.h"
    2. void TestVector1()
    3. {
    4. my::vector<int> v; //注意类域,这里使用模拟的vector,要加上类名
    5. v.push_back(2);
    6. v.push_back(0);
    7. v.push_back(2);
    8. v.push_back(2);
    9. v.push_back(8);
    10. 1.使用范围for遍历
    11. //for (auto e : v)
    12. //{
    13. // cout << e << " ";
    14. //}
    15. //cout << endl;
    16. //2.使模拟迭代器遍历
    17. my::vector<int>::iterator it = v.begin();
    18. while (it != v.end())
    19. {
    20. cout << *it << " ";
    21. ++it;
    22. }
    23. cout << endl;
    24. }
    25. void TestVector2()
    26. {
    27. my::vector<int> v;
    28. v.push_back(2);
    29. v.push_back(0);
    30. v.push_back(2);
    31. v.push_back(2);
    32. v.push_back(8);
    33. //模拟迭代器遍历
    34. my::vector<int>::iterator it = v.begin();
    35. while (it != v.end())
    36. {
    37. cout << *it << " ";
    38. ++it;
    39. }
    40. cout << endl;
    41. v.pop_back();
    42. v.pop_back();
    43. v.pop_back();
    44. //1.下标+[] 进行遍历 有3种遍历方式
    45. for (size_t i = 0; i < v.size(); ++i)
    46. {
    47. cout << v[i] << " ";
    48. }
    49. cout << endl;
    50. }
    51. void TestVector3()
    52. {
    53. my::vector<int> v;
    54. v.resize(6, 6);
    55. for (auto e : v)
    56. {
    57. cout << e << " ";
    58. }
    59. cout << endl;
    60. }
    61. void TestVector4()
    62. {
    63. my::vector<int> v;
    64. v.push_back(1);
    65. v.push_back(2);
    66. v.push_back(3);
    67. v.push_back(4);
    68. //v.push_back(5);
    69. //模拟迭代器遍历
    70. my::vector<int>::iterator it = v.begin();
    71. while (it != v.end())
    72. {
    73. cout << *it << " ";
    74. ++it;
    75. }
    76. cout << endl;
    77. v.insert(v.begin(), 0);
    78. //v.insert(v.begin()+2, 0);
    79. for (auto e : v)
    80. {
    81. cout << e << " ";
    82. }
    83. cout << endl;
    84. }
    85. void TestVector5()
    86. {
    87. //在所有的偶数前面插入9
    88. my::vector<int> v;
    89. //v.reserve(10);
    90. v.push_back(1);
    91. v.push_back(2);
    92. v.push_back(3);
    93. v.push_back(4);
    94. v.push_back(5);
    95. for (auto e : v)
    96. {
    97. cout << e << " ";
    98. }
    99. cout << endl;
    100. my::vector<int>::iterator it = v.begin();
    101. while (it != v.end())
    102. {
    103. if (*it % 2 == 0)
    104. {
    105. it=v.insert(it, 9); //insert扩容以后,it就失效了,it值传递给pos,pos改变不影响it
    106. //it指向的位置变了
    107. ++it;
    108. }
    109. ++it;
    110. }
    111. for (auto e : v)
    112. {
    113. cout << e << " ";
    114. }
    115. cout << endl;
    116. }
    117. void TestVector6()
    118. {
    119. my::vector<int> v;
    120. v.push_back(1);
    121. v.push_back(2);
    122. v.push_back(3);
    123. v.push_back(4);
    124. for (auto e : v)
    125. {
    126. cout << e << " ";
    127. }
    128. cout << endl;
    129. cout << "v.size():" << v.size()<<" " << "v.capacity:" << v.capacity() << endl;
    130. auto pos = find(v.begin(), v.end(), 2);
    131. if (pos != v.end())
    132. {
    133. v.erase(pos);
    134. }
    135. for (auto e : v)
    136. {
    137. cout << e << " ";
    138. }
    139. cout << endl;
    140. cout << "v.size():" << v.size() << " " << "v.capacity:" << v.capacity() << endl;
    141. cout << *pos << endl;
    142. *pos = 10;
    143. for (auto e : v)
    144. {
    145. cout << e << " ";
    146. }
    147. }
    148. void TestVector7()
    149. {
    150. //删除所有的偶数
    151. my::vector<int> v;
    152. //std::vector v; //库里的vector
    153. v.push_back(2);
    154. v.push_back(1);
    155. v.push_back(2);
    156. v.push_back(2);
    157. v.push_back(2);
    158. v.push_back(3);
    159. v.push_back(4);
    160. v.push_back(5);
    161. v.push_back(6);
    162. v.push_back(6);
    163. v.push_back(6);
    164. v.push_back(6);
    165. v.push_back(5);
    166. for (auto e : v)
    167. {
    168. cout << e << " ";
    169. }
    170. cout << endl;
    171. auto it = v.begin();
    172. while (it != v.end())
    173. {
    174. if (*it % 2 == 0)
    175. {
    176. it=v.erase(it); //处理迭代器失效问题的解决方式
    177. }
    178. else
    179. {
    180. ++it;
    181. }
    182. }
    183. for (auto e : v)
    184. {
    185. cout << e << " ";
    186. }
    187. cout << endl;
    188. }
    189. void TestVector8()
    190. {
    191. my::vector<int> v1;
    192. v1.push_back(1);
    193. v1.push_back(2);
    194. v1.push_back(3);
    195. v1.push_back(4);
    196. for (auto e : v1)
    197. {
    198. cout << e << " ";
    199. }
    200. cout << endl;
    201. my::vector<int> v2(v1.begin(), v1.end());
    202. std::string s("hello");
    203. my::vector<int> v3(s.begin(), s.end());
    204. for (auto e : v2)
    205. {
    206. cout << e << " ";
    207. }
    208. cout << endl;
    209. for (auto e : v3)
    210. {
    211. cout << e << " ";
    212. }
    213. cout << endl;
    214. }
    215. void TestVector9()
    216. {
    217. my::vector<int> v1;
    218. v1.push_back(1);
    219. v1.push_back(2);
    220. v1.push_back(3);
    221. v1.push_back(4);
    222. for (auto e : v1)
    223. {
    224. cout << e << " ";
    225. }
    226. cout << endl;
    227. my::vector<int> v2(v1); //拷贝构造
    228. for (auto e : v2)
    229. {
    230. cout << e << " ";
    231. }
    232. cout << endl;
    233. my::vector<int> v3;
    234. v3 = v1; //赋值
    235. for (auto e : v3)
    236. {
    237. cout << e << " ";
    238. }
    239. cout << endl;
    240. }
    241. void TestVector10()
    242. {
    243. //使用n个val构造函数
    244. my::vector<int> v1(10,2);
    245. for (auto e : v1)
    246. {
    247. cout << e << " ";
    248. }
    249. cout << endl;
    250. my::vector<char> v2(10, 'q');
    251. for (auto e : v2)
    252. {
    253. cout << e << " ";
    254. }
    255. cout << endl;
    256. }
    257. void TestVector11()
    258. {
    259. //杨辉三角
    260. class Solution
    261. {
    262. public:
    263. my::vectorint>> generate(int numRows)
    264. {
    265. my::vectorint>> vv;
    266. vv.resize(numRows);
    267. for (size_t i = 0; i < vv.size(); ++i)
    268. {
    269. //每次每行个数递增1
    270. vv[i].resize(i + 1, 0);
    271. vv[i][0] = 1;
    272. vv[i][vv[i].size() - 1] = 1;
    273. }
    274. for (int i = 0; i < vv.size(); ++i)
    275. {
    276. for (int j = 0; j < vv[i].size(); ++j)
    277. {
    278. if (vv[i][j] == 0)
    279. {
    280. //中间位置等于上一行j-1列和j列相加
    281. vv[i][j] = vv[i - 1][j - 1] + vv[i - 1][j];
    282. }
    283. cout << vv[i][j] << " ";
    284. }
    285. cout << endl;
    286. }
    287. cout << endl;
    288. return vv;
    289. }
    290. };
    291. my::vectorint>> vv = Solution().generate(7);
    292. for (int i = 0; i < vv.size(); ++i)
    293. {
    294. for (int j = 0; j < vv[i].size(); ++j)
    295. {
    296. cout << vv[i][j] << " ";
    297. }
    298. cout << endl;
    299. }
    300. }
    301. int main()
    302. {
    303. //TestVector1();
    304. //TestVector2();
    305. //TestVector3();
    306. //TestVector4();
    307. //TestVector5();
    308. //TestVector6();
    309. //TestVector7();
    310. //TestVector8();
    311. //TestVector9();
    312. //TestVector10();
    313. TestVector11();
    314. return 0;
    315. }

    2.2例题:使用vector实现杨辉三角:

     

    后记:
    ●由于作者水平有限,文章难免存在谬误之处,敬请读者斧正,俚语成篇,恳望指教!
                                                                      ——By 作者:新晓·故知

     

  • 相关阅读:
    微信聊天功能测试用例
    @umijs/plugin-locale使用
    Pipenv
    100 余个网页设计优化案例(用户体验、交互优化等方面)
    AOP 编程
    【数据结构】图 常见题型汇总
    RabbitMQ的高级特性
    基于Swagger的接口自动化测试
    CSS 网页布局
    echarts折线图(其他图也是一样)设置tooltip自动滚动
  • 原文地址:https://blog.csdn.net/m0_57859086/article/details/126165377