你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

vector是C++标准模板库中的部分内容,该如何使用?

[复制链接]
gaosmile 发布时间:2020-5-31 19:11
vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库。vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单地说,vector是一个能够存放任意类型的动态数组,能够增加和压缩数据。  
% y5 D+ M' i7 Y2 B, t  l6 \
. u0 e, T& Q6 c

$ o, ]. n- b0 q7 V" j  k3 p2 ^为了可以使用vector,必须在你的头文件中包含下面的代码:  
, @/ `% q! A* B5 x5 y4 T#include <vector>  6 Y9 h' l9 u: q
vector属于std命名域的,因此需要通过命名限定,如下完成你的代码:  
& X& ?/ [! P5 v, W" Yusing std::vector;  
* v3 U! ?" e* g% Tvector<int> vInts;  
( {* O, Q" d- t* ?& K6 v1 f4 O: Z) ]或者连在一起,使用全名:  $ j' e, T! U. g$ N
std::vector<int> vInts;  5 B/ S# h3 ~2 C# B- [9 a
建议使用全局的命名域方式:using namespace std;  9 {) v/ C4 f. l* |, @+ G
函数  ! y! }8 J4 t4 ^% S
表述  ; b1 ?5 {5 g0 L% N: J4 J
c.assign(beg,end)c.assign(n,elem)  $ t* |" L% n% t! t$ B; ?
将[beg; end)区间中的数据赋值给c。将n个elem的拷贝赋值给c。  
0 {% ]2 _) a' i- I% b! pc.at(idx)  # j. A8 a3 F) T3 e  l0 j
传回索引idx所指的数据,如果idx越界,抛出out_of_range。  
; v* b0 D/ r7 K9 D: Jc.back()    ^! m; `, i' |" D
传回最后一个数据,不检查这个数据是否存在。  1 |- ~5 Y1 |4 E4 U1 w. @, [
c.begin()  
4 Z- J4 G) q+ _9 L5 a" f传回迭代器中的第一个数据地址。  : i, r; x' ~7 @4 B
c.size()  . a( j( N! R- p) p
返回容器中数据个数。  ; O% K. B: i2 R, A% y! W( e% v
c.clear()  
  Z- ~  I6 u$ h) g; X" N. I1 p% I3 D9 L5 x移除容器中所有数据。  
+ p' ?: I. H! qc.empty()  
" t9 p& {) q7 r1 A判断容器是否为空。  $ y6 o" b; z  |5 T, a$ ]) O6 E
c.end()  ' q$ C# Q5 U! N# i
指向迭代器中末端元素的下一个,指向一个不存在元素。  - m" M- }& o4 a- @; s$ x0 G  ?
c.erase(pos)  
/ p$ g) O* {- U/ qc.erase(beg,end)  
/ d$ l  x8 \" K) N8 {. O4 Q; Q. K0 X删除pos位置的数据,传回下一个数据的位置。  , z  e+ i8 w# R7 m
删除[beg,end)区间的数据,传回下一个数据的位置。  
' X2 ^4 i. W0 ^+ r3 f6 v, Fc.front()  ) r9 x5 @9 p: r' m+ R5 L! `3 A
传回第一个数据。  8 p! {' x/ I5 f( W, G6 d) D
get_allocator  & U- V: d! X! f6 V) E) q
使用构造函数返回一个拷贝。  + D% S0 V8 X# c7 e% h. R# A3 a5 j
c.insert(pos,elem)  
7 A4 T$ _' }: k% H, M: {! ]c.insert(pos,n,elem)  8 C6 g/ C+ g6 ]
c.insert(pos,beg,end)  % `, P5 h$ U0 |8 u' m$ q
) K+ a5 n8 \  s+ t  y( T2 u* K
; _, k8 u" z% r# i" p% v
在pos位置插入一个elem拷贝,传回新数据位置。在pos位置插入n个elem数据。无返回值。在pos位置插入在[beg,end)区间的数据。无返回值。! x! [+ s/ G' U
  ; U: U% [! b* @1 L- V$ o' y( K+ j
c.max_size()  1 j/ V; a4 ?2 [6 E
返回容器中最大数据的数量。  
3 h8 d( a" V0 h2 Jc.pop_back()  
4 ?1 x2 S2 s+ M5 ~. w删除最后一个数据。  
/ B! D- N6 m% K( d3 Ec.push_back(elem)  2 x+ t  I4 |; `1 b! d; G$ @$ j
在尾部加入一个数据。  
$ S+ A! L; w$ Tc.rbegin()  
/ {1 q7 ~9 C$ t9 ~' k传回一个逆向队列的第一个数据。  
, T4 F( K- h4 I, M! Rc.rend()  
5 t1 m2 H1 V0 w传回一个逆向队列的最后一个数据的下一个位置。  
7 R6 M3 M7 C& p0 L- ic.resize(num)  
9 D4 w% U6 I! O3 c5 y0 @重新指定队列的长度。  ( f+ `* f, L. i
c.reserve()  ) E  V% j. C' r
保留适当的容量。  
0 k# B6 {" k6 b% zc.size()  
  d7 V3 l8 ?; ?- r  o$ s返回容器中实际数据的个数。  " [. ?! ]" S" u- J& q4 M# I$ E5 E
c1.swap(c2)  # a# v" G. G/ ~- M( V: g6 V8 Z
swap(c1,c2)  5 r% g! d* R8 n: ~! p8 x) k
将c1和c2元素互换。同上操作。  
$ _5 _- l1 N3 q% l0 B$ ~5 ?) avector<Elem>  
$ j  O% K) F+ t2 ^- Icvector<Elem> c1(c2)  
  Z/ F/ z: K6 q4 qvector <Elem> c(n)  
' W1 k- i0 `; c3 \9 g$ |9 m  N0 v: _ector <Elem> c(n, elem)  
4 y2 N% y% b, F$ M$ e+ v0 Xvector <Elem> c(beg,end)  
9 g* h  M: q  y3 h0 i! Yc.~ vector <Elem>()  
3 \6 G" B9 N9 n  n+ r
9 w7 C  K* I5 ]! y
# A% A8 h' L! r
创建一个空的vector。复制一个vector。创建一个vector,含有n个数据,数据均已缺省构造产生。创建一个含有n个elem拷贝的vector。创建一个以[beg;end)区间的vector。销毁所有数据,释放内存。  
0 e, r' Q9 o3 h! V: u
: Z# Y5 e( \  W% u

; S/ Y2 X! Z. n$ Q7 a8 p) J. ~/ @operator[]  : F  G7 _& C% p6 x- L
返回容器中指定位置的一个引用。  
7 K; R. h0 e, z% k" _6 C创建一个vector  * D5 W7 b1 H# ^& e
vector容器提供了多种创建方法,下面介绍几种常用的。  & a1 M1 ~) {$ _/ [0 `7 R
创建一个Widget类型的空的vector对象:  5 e7 w# S( r+ C' j+ y' p
vector<Widget> vWidgets;  
" ^7 B; |' d3 M, M: j创建一个包含500个Widget类型数据的vector:  ) n! b) c6 `, n" @9 L) i! H
vector<Widget> vWidgets(500);  " R/ j& u& a5 ]% Y3 J+ @( L, u
创建一个包含500个Widget类型数据的vector,并且都初始化为0:  
4 \) a; J) ~! J6 ~vector<Widget> vWidgets(500, Widget(0));  
1 o; T: {* `4 v3 Y2 ]7 ]8 j创建一个Widget的拷贝:  * Z# Q0 w9 A- d; _9 ?1 `
vector<Widget> vWidgetsFromAnother(vWidgets);  
, U4 ^) y8 V# m/ G+ ~向vector添加一个数据 
  F5 ~; Y7 B; q, U! t. i5 U2 } ! `- n+ L) L2 ~8 ^% A/ b$ A
vector添加数据的缺省方法是push_back()。push_back()函数表示将数据添加到vector的尾部,并按需要来分配内存。例如:向vector<Widget>中添加10个数据,需要如下编写代码:
1 Z8 ?# M! T- {3 _  for(int i= 0;i<10; i++) {
% o4 G; e6 b/ z, p7 ]( }  vWidgets.push_back(Widget(i));
2 I  X& \! \" _2 @( I/ a  }4 C. v% w+ j2 R" c' j) P
  获取vector中制定位置的数据  
' L) h. n5 p3 i5 V* @* f
; |0 B" t8 P2 a) w, J4 R' y+ C
& S# R4 c- U# g0 q( a7 K
vector里面的数据是动态分配的,使用push_back()的一系列分配空间常常决定于文件或一些数据源。如果想知道vector存放了多少数据,可以使用empty()。获取vector的大小,可以使用size()。例如,如果想获取一个vector v的大小,但不知道它是否为空,或者已经包含了数据,如果为空想设置为-1,你可以使用下面的代码实现:
, t- c7 y; K( W& I. A* Y, w: L  int nSize = v.empty() ? -1 : static_cast<int>(v.size());
9 r$ a2 m& q+ {7 `  访问vector中的数据! A& i7 f9 n, ^8 Z6 w) y
  使用两种方法来访问vector。
* a. n8 k& }, k" \# Z. e  1、 vector::at(); K5 ?# }/ @* F! d2 ?
  2、 vector:perator[]
4 N/ b' G: V4 c+ ^
. L% v) T+ z- F' w1 W( v7 t

7 P# n5 w3 Q% Q/ s# [3 {operator[]主要是为了与C语言进行兼容。它可以像C语言数组一样操作。但at()是我们的首选,因为at()进行了边界检查,如果访问超过了vector的范围,将抛出一个例外。由于operator[]容易造成一些错误,所有我们很少用它,下面进行验证一下:
9 H8 p$ s5 _5 Z6 s  分析下面的代码:
' i9 `, x  J! m- R- ?  vector<int> v;6 a# x, Z' C4 ~' ~
  v.reserve(10);
% Z. F0 F* v4 r' E5 m1 U# J- b) \  for(int i=0; i<7; i++) {
. ~4 S8 M* ]0 V7 P. ]* t  v.push_back(i);! ~& w# O6 Q, _. B
  }2 O/ |0 f* s9 {* w4 F  m$ k/ K4 C
  try {int iVal1 = v[7];! x, D- R3 P% U9 D
  // not bounds checked - will not throw! x9 S5 I2 ~3 s) g( h
  int iVal2 = v.at(7);- S( N- K* }/ r
  // bounds checked - will throw if out of range
$ m/ g6 M$ x+ J0 u' |  } catch(const exception& e) {" w! R% k7 y$ l. M6 d  E
  cout << e.what();
& _) j% w& U: U6 Q& p! v6 {" h  }
' d2 L% f. W( }+ J  删除vector中的数据
1 w- H7 o& @: H" P
( \2 F' S6 @" s4 b2 ~

! A% C9 u7 i) s! dvector能够非常容易地添加数据,也能很方便地取出数据,同样vector提供了erase(),pop_back(),clear()来删除数据,当删除数据时,应该知道要删除尾部的数据,或者是删除所有数据,还是个别的数据。  
" C. H4 L7 `- p3 h/ x: `6 i! q4 q  j) j, h4 l6 d) U* j2 W

1 {* l* ]- ?6 i* R7 PRemove_if()算法 如果要使用remove_if(),需要在头文件中包含如下代码::9 Y6 f# C& ]1 `4 q* |, _/ F# d
  #include <algorithm>
8 T1 B5 g" @3 \" G& B  Remove_if()有三个参数:9 ?* a% S- I) V9 J: |
  1、 iterator _First:指向第一个数据的迭代指针。
3 q& a/ G8 c5 D) T, v  2、 iterator _Last:指向最后一个数据的迭代指针。3 a( k% X8 u5 H! I. r' r  X
  3、 predicate _Pred:一个可以对迭代操作的条件函数。1 P% Q6 C/ w3 C# @3 Q
6 i( Y+ o  x1 l% r' z
0 _( v& d$ T8 u7 Z  G% j" a
  条件函数  
6 a- b( F+ _3 @* A" p& h- M0 w5 V1 C
( {- R& q& ~- ~, n
条件函数是一个按照用户定义的条件返回是或否的结果,是最基本的函数指针,或是一个函数对象。这个函数对象需要支持所有的函数调用操作,重载operator()()操作。remove_if()是通过unary_function继承下来的,允许传递数据作为条件。  % x. \/ |7 w' M) z

4 X1 c) ~# a7 X. e5 W& q

, X6 i' b. t+ h# @例如,假如想从一个vector<CString>中删除匹配的数据,如果字串中包含了一个值,从这个值开始,从这个值结束。首先应该建立一个数据结构来包含这些数据,类似代码如下:
4 l3 K: [( a% ~1 R" r) {  #include <functional>
/ W2 a) D+ P9 N7 q; l3 `) [2 o7 b+ B$ C  enum findmodes {
: v4 X3 o* }" M; H+ }9 E  FM_INVALID = 0,6 }* ]% a2 s  X3 w% t% a% {# J+ O
  FM_IS,
4 J' B, V$ Y0 _2 L) b  FM_STARTSWITH,
( r0 z) u" N. N  FM_ENDSWITH,
0 {/ N$ w! b5 n$ b  FM_CONTAINS
- F2 \5 L  d9 J0 l  };
) s# H8 W, }3 ?# w  typedef struct tagFindStr {
, h8 F! G2 \# p6 J  UINT iMode;
; W! R4 M" }$ a  CString szMatchStr;4 p! M" A' n3 }% Y3 n
  } FindStr;5 l; n2 |, ~# S9 a( g
  typedef FindStr* LPFINDSTR;
. p0 }2 M# J$ h  然后处理条件判断:
" D6 p) w2 o) A8 ?7 ~4 d! D  class FindMatchingString : public std::unary_function<CString, bool> {) P+ j* ~  C$ L3 R1 D) i
  public:
8 c4 f  J$ L3 d- \+ A  FindMatchingString(const LPFINDSTR lpFS) :4 p* J$ W. @) {# ?- V
  m_lpFS(lpFS) {
* q1 r# W& s; x6 U7 U  }
2 J" Z6 @. l: x  bool operator()(CString& szStringToCompare) const {$ u( @1 A: b8 k. b, [5 r
  bool retVal = false;
9 Z) U2 U, i9 F  v' r7 E  switch (m_lpFS->iMode) {
0 F5 s0 X. J5 Z# j$ m9 H  case FM_IS: {) ?( ?# t. i& P3 F1 r: N
  retVal = (szStringToCompare == m_lpFDD->szMatchStr);, w+ H7 U+ [% ^( @
  break;1 H* |/ L9 R; ^( b' m
  }7 J# d( r- y, G8 x
  case FM_STARTSWITH: {
1 r3 M; o8 k0 q7 w  retVal = (szStringToCompare.Left(m_lpFDD->szMatchStr.GetLength())% b) e9 t0 t- j# Q
  == m_lpFDD->szWindowTitle);
  Z$ y$ u% h1 r" {: R  break;
7 ^7 v4 I; i; K0 B  }
( u* @4 U. }( w( B  case FM_ENDSWITH: {' \: t; m+ g, ]  j0 |# P$ V( r6 M
  retVal = (szStringToCompare.Right(m_lpFDD->szMatchStr.GetLength())
1 m8 J: e  U1 |, ?: ?  == m_lpFDD->szMatchStr);
, M! V3 H  M9 A1 j  break;2 W3 E1 {" F% F& G+ }; C& }
  }3 D" I! D' f. n0 @7 F
  case FM_CONTAINS: {
5 h5 S0 u' k% k! e6 q  retVal = (szStringToCompare.Find(m_lpFDD->szMatchStr) != -1);
8 Q3 i: Q) k3 Q8 j6 a) P$ J( ]  break;
/ K: f, o' n/ C- N/ Z+ |  }
8 s1 ]; K3 G# c; X# G/ G  }$ l% C* b7 Q5 |8 y  G* `: e! b9 I
  return retVal;9 V, _3 F: W+ t
  }
) H  w5 r- o! u+ p7 N  private:
, L6 |) [' d' R/ \$ ]" W  LPFINDSTR m_lpFS;+ H. n8 o  K/ a  C2 M. N
  };
+ G$ N' W3 k& W0 O  通过这个操作你可以从vector中有效地删除数据:
! q/ B" r: P. [/ t. p* n  FindStr fs;1 }" j3 c6 h$ |1 I7 U: ?6 k* `2 h$ \
  fs.iMode = FM_CONTAINS;
+ g; ~5 M. ~8 @, E) }/ e2 d  fs.szMatchStr = szRemove;
% N3 _7 x2 u  d7 B2 O. Q3 l4 g* P  vs.erase(std::remove_if(vs.begin(), vs.end(), FindMatchingString(&fs)), vs.end());  9 X3 g) v% i' [: Y
$ m/ w9 X- A4 y& r2 r

7 L& j' a8 M! |* I7 s% r5 wRemove(),remove_if()等所有的移出操作都是建立在一个迭代范围上的,不能操作容器中的数据。所以在使用remove_if(),实际上操作的时容器里数据的上面的。  + A6 Y, }3 k/ ?6 d* {+ Z

3 G6 G! h8 F* n

  [/ |, W' v, [" t看到remove_if()实际上是根据条件对迭代地址进行了修改,在数据的后面存在一些残余的数据,那些需要删除的数据。剩下的数据的位置可能不是原来的数据,但他们是不知道的。  
2 J7 B7 e) U( P% N
6 a' D' I$ [6 e0 W! I
& S5 \! x# V+ v
调用erase()来删除那些残余的数据。注意上面例子中通过erase()删除remove_if()的结果和vs.enc()范围的数据。' t# k- L6 J6 @0 Y
/ F, O- N9 U! d/ ?7 y5 T$ U8 U
赞 收藏 评论1 发布时间:2020-5-31 19:11

举报

1个回答
李康1202 回答时间:2020-6-1 09:35:30
谢谢分享
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版