日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

C++笔记 —— vector常用方法

發(fā)布時(shí)間:2024/6/21 综合教程 26 生活家
生活随笔 收集整理的這篇文章主要介紹了 C++笔记 —— vector常用方法 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本篇中使用的調(diào)試函數(shù)如下

 1 template<typename T>
 2 void print_vector(vector<T> a){
 3     if(a.size() == 0)
 4         cout << "empty" << endl;
 5     else{
 6         for(int i = 0; i < a.size(); i++)
 7             cout << a[i] << " ";
 8         cout << endl;
 9     }
10 }

1.vector的初始化

 1 vector<double> a; // 生成空向量
 2 vector<double> b(5); // 指定大小,每個(gè)元素都是初始值0
 3 vector<double> c{1,2,3,4,5}; // 指定每一個(gè)元素的值
 4 vector<double> d(5,3); // 指定大小和統(tǒng)一初始化值
 5 vector<double> e(c); // 復(fù)制構(gòu)造函數(shù)
 6 vector<double> f(begin(e), begin(e) + 3); // 部分復(fù)制構(gòu)造
 7 
 8 print_vector(a); // empty
 9 print_vector(b); // 0 0 0 0 0
10 print_vector(c); // 1 2 3 4 5
11 print_vector(d); // 3 3 3 3 3
12 print_vector(e); // 1 2 3 4 5
13 print_vector(f); // 1 2 3

2.向vector中增加(或者是插入)元素

 1 vector<int> a; 
 2 vector<int> b{4,5,6};
 3 
 4 a.push_back(1); //在末端增加1個(gè)元素
 5 print_vector(a); // 1
 6 
 7 a.emplace_back(2);//同在末端增加1個(gè)元素,比push_back()效率更高
 8 print_vector(a); // 1 2
 9 
10 a.insert(begin(a) + 1, 3);//在迭代器指定的位置插入單個(gè)元素
11 print_vector(a); // 1 3 2
12 
13 a.insert(end(a),begin(b),end(b));//三個(gè)參數(shù)都是迭代器,向第一個(gè)參數(shù)指定的位置中插入從第二個(gè)參數(shù)到第三個(gè)參數(shù)中的元素
14 print_vector(a); // 1 3 2 4 5 6
15 
16 a.insert(end(a) - 1, 2, 7);//往第一個(gè)參數(shù)(迭代器)指定的位置插入以第二個(gè)參數(shù)為個(gè)數(shù)的第三個(gè)參數(shù)
17 print_vector(a); // 1 3 2 4 5 7 7 6
18 
19 a.insert(end(a) - 2, {8,9});//第一個(gè)參數(shù)是插入位置,第二個(gè)參數(shù)是插入的參數(shù)(初始化列表形式)
20 print_vector(a); // 1 3 2 4 5 7 8 9 7 6

3.向vector中刪除某些元素

在這里暫時(shí)先不介紹remove,對(duì)于單純想要?jiǎng)h除元素,remove是不被建議的做法。還有pop_back()用于刪除最后一個(gè)元素

 1 vector<int> a{1,2,3,4,5,6,7,8,9};
 2 
 3 a.pop_back(); // 刪除vector中最后的單個(gè)元素
 4 print_vector(a); // 1 2 3 4 5 6 7 8
 5 
 6 a.erase(a.begin() + 1); // 刪除由迭代器指定的位置中的單個(gè)元素
 7 print_vector(a); // 1 3 4 5 6 7 8
 8 
 9 a.erase(a.begin() + 2, a.begin() + 4); // 刪除兩個(gè)迭代器之間的元素
10 print_vector(a); // 1 3 6 7 8

4.查找

vector支持隨機(jī)訪問,可以用方括號(hào)運(yùn)算符實(shí)現(xiàn)按下標(biāo)查找。

按值查找主要用到algorithm中的find()和find_if()兩個(gè)算法:

find()函數(shù)有三個(gè)參數(shù),第一二個(gè)參數(shù)都是迭代器,分別指向要查找的區(qū)間的起始點(diǎn)和終止點(diǎn),第三個(gè)參數(shù)是一個(gè)特定的值,說明要查找的元素。如果找到則返回一個(gè)指向第一個(gè)符合條件的元素的迭代器,如果沒有找到則返回指向查找區(qū)間終點(diǎn)的迭代器(也就是和第二個(gè)參數(shù)一樣)。find()函數(shù)不僅可以查找基本數(shù)據(jù)類型的vector,也可以查找自定義的類的vector,要求是自定義的類中重載了==運(yùn)算符。

find_if()可以實(shí)現(xiàn)更廣義的查找。find_if()前兩個(gè)參數(shù)和find()一樣,第三個(gè)參數(shù)是一個(gè)函數(shù)func,func只有一個(gè)參數(shù),參數(shù)類型是被查找的元素的類型,返回值是bool類型,find_if()會(huì)返回使得func返回值為真的元素的迭代器。如果找不到則返回指向查找區(qū)間末端的迭代器。

最后是一個(gè)小技巧:使用find()或find_if()查找到的指向某個(gè)元素的迭代器,減去指向該vector的頭部的迭代器(也就是begin()),可以得到該元素的下標(biāo),也就是按值查找下標(biāo)功能。

 1 class Student{
 2 public:
 3     int year;
 4     int grade;
 5     Student(int y, int g):year(y), grade(g){}
 6     bool operator==(const Student & Other){
 7         return (year == Other.year);
 8     }
 9 };
10 
11 bool excellent(Student s){
12     return s.grade > 85;
13 }
14 
15 int main(){
16     vector<Student> a{Student(17,80), Student(16,95), Student(18,70)};
17 
18     cout << "year: " << a[2].year << " grade: " << a[2].grade << endl; // 根據(jù)下標(biāo)查找值
19 
20     vector<Student>::iterator b = find(begin(a), end(a), Student(18,100));
21     cout << b - begin(a) << endl;/*利用find的結(jié)果可以做到根據(jù)值查找下標(biāo)*/
22 
23     auto d = find_if(begin(a), end(a), excellent);
24     cout << d - begin(a)<< endl;
25 }

在這個(gè)例子中,find()函數(shù)查找的判斷依據(jù)是Student類中的==運(yùn)算符(例子中只要求找到第一個(gè)年齡等于18歲的學(xué)生),而find_if()中查找判斷的依據(jù)是用戶自己定義的excellent函數(shù)(例子中是要求找到第一個(gè)成績大于85分的學(xué)生)

最后,由于find_if()的判斷是自定義的函數(shù),實(shí)際上有更多更靈活的寫法,比如重載類的()操作符成為成員函數(shù),或者使用lambda表達(dá)式等。

5.修改

C++似乎并沒有python那種直接指把一個(gè)指定區(qū)間的元素整個(gè)替換成另一個(gè)區(qū)間的元素的操作。由于vector的實(shí)現(xiàn)是動(dòng)態(tài)數(shù)組,往數(shù)組中插入或者刪除元素的時(shí)間復(fù)雜度都是O(n),如無必要不要經(jīng)常反復(fù)增刪vector元素.assign有兩種使用方式,但是這兩種使用方式都會(huì)直接清除這個(gè)向量之前內(nèi)部的所有數(shù)據(jù)。隨機(jī)訪問還可以用at,作用一樣。

 1 vector<int> a{1,2,3};
 2 vector<int> b{4,5,6,7};
 3 a[1] = 0;
 4 print_vector(a); // 1 0 3
 5 
 6 a.assign(begin(b), end(b));
 7 print_vector(a); // 4 5 6 7
 8 
 9 a.assign(5,2);
10 print_vector(a); // 2 2 2 2 2

6.排序

使用vector內(nèi)自帶的排序功能排序,對(duì)兩個(gè)迭代器內(nèi)指定的區(qū)間按照自定義的方式進(jìn)行排序,cmp參數(shù)是兩個(gè)待比較的值類型,返回值是bool類型

 1 class A{
 2 public:
 3     int n, m;
 4     A(int N, int M):n(N), m(M){}
 5 };
 6 
 7 bool cmp(A p1, A p2){
 8     return (p1.m > p2.m);
 9 }
10 
11 int main(){
12     vector<A> a{A(1,4),A(3,3),A(2,5),A(5,1),A(4,2)};
13     sort(a.begin(), a.end(), cmp); // 按照m從大到小排序
14 }

7.迭代器

迭代器本質(zhì)上就是指向元素的指針,跟指針的用法差不多,對(duì)于指向同一個(gè)容器的兩個(gè)迭代器iter1和iter2,可以使用自加/自減或者加減某一個(gè)整數(shù)的操作使得迭代器左右移動(dòng)。也可以用比較運(yùn)算符==和!=(只有vector和queue的迭代器才可以使用<和>比較)。同時(shí)還可以相減得出下標(biāo)的差值。由于迭代器相當(dāng)于指針,因此可以使用*解引用或者如果是類可以使用->取其成員變量。

特殊的迭代器有begin和end,以及rbegin和rend可以用來初始化迭代器。

注意區(qū)分front,back和being,end,前者的兩個(gè)分別返回的是第一個(gè)元素和最后一個(gè)元素的引用。

1 vector<double> a{1.1, 2.2, 3.3, 4.4, 5.5};
2 vector<double>::iterator iter1 = a.begin();
3 auto mid = iter1 + a.size() / 2;
4 cout << *mid << endl;

8.其他

size()獲取大小,reverse()翻轉(zhuǎn),clear()清除所有元素,swap()交換元素,resize()改變大小(如果大于現(xiàn)大小則往后補(bǔ)默認(rèn)元素,小于現(xiàn)大小則在尾端刪除至要求的大小),capacity()獲取容量(當(dāng)vector大小達(dá)到容量上限時(shí)會(huì)啟動(dòng)自動(dòng)擴(kuò)容,但是自動(dòng)擴(kuò)容是一件很耗時(shí)間的事情,而且自動(dòng)擴(kuò)容期間會(huì)導(dǎo)致現(xiàn)有的迭代器和指針失效。所以實(shí)現(xiàn)估計(jì)大小并提前申請(qǐng)好容量大小是必要的。),reserve()手動(dòng)擴(kuò)容,count()統(tǒng)計(jì)某個(gè)元素出現(xiàn)次數(shù)。

最后重點(diǎn)說明兩個(gè):

1.remove()可以實(shí)現(xiàn)類似于“刪除”某個(gè)元素的功能,以數(shù)組b[2,3,4,3,5]為例,如果想remove(begin(b),end(b),3),將會(huì)執(zhí)行以下幾步

  申請(qǐng)兩個(gè)指針i,j都指向b[0]

  *i 不等于3(也就是b[0]),把i指向元素的值賦給j指向元素的值(b[0] <- b[0])++i,++j

  *i 等于3(也就是b[1]),++i,j不動(dòng)(j相當(dāng)于標(biāo)記了一個(gè)坑的位置)

  *i 不等于3(也即是b[2]),把i指向元素的值賦給j指向元素的值(b[1] <- b[3])++i,++j

  *i 等于3(也就是b[3]),++i,j不動(dòng)

  *i 不等于3(也即是b[4]),把i指向元素的值賦給j指向元素的值(b[2] <- b[5])++i,++j

  最后的結(jié)果就是[2,4,5,3,5],從過程可以看出,是吧所有非3的元素都往前移,把原來是3的位置補(bǔ)上,而后面多出來的位置保持不變。remove返回值是就是上文中的j。

  因此,想要用remove真正刪除元素3,應(yīng)該寫成:

  1 b.erase(remove(begin(b), end(b),3), end(b));

2.去重:想要去除vector中的重復(fù)元素有兩種思路:

  一是把vector轉(zhuǎn)換成set再轉(zhuǎn)換成vector

  二是sort+unique+erase(unique的作用是把所有相鄰且重復(fù)的元素放到列表末尾)

 1 vector<int> a{1,2,3,4,5,6,7,8,9};
 2 cout << a.size() << endl; // 輸出9
 3 
 4 reverse(begin(a),end(a)); // reverse是algorithm中的函數(shù),用于翻轉(zhuǎn)
 5 print_vector(a); // 9 8 7 6 5 4 3 2 1
 6 
 7 remove(begin(a), end(a), 5);
 8 print_vector(a); // 9 8 7 6 4 3 2 1 1
 9 
10 reverse(begin(a), end(a));
11 print_vector(a); // 1 1 2 3 4 6 7 8 9
12 
13 swap(a[0], a[2]);
14 print_vector(a); // 2 1 1 3 4 6 7 8 9
15 
16 a.resize(12);
17 print_vector(a); // 2 1 1 3 4 6 7 8 9 0 0 0
18 
19 a.resize(5);
20 print_vector(a); // 2 1 1 3 4
21 
22 cout << "Capacity: " << a.capacity() << endl; // 18
23 a.reserve(30);
24 cout << "Capacity: " << a.capacity() << endl; // 30
25 
26 cout << "Num of 1: " << count(begin(a), end(a), 1) << endl; // 2
27 
28 a.clear();
29 cout << a.empty() << endl; // 輸出1,即true

總結(jié)

以上是生活随笔為你收集整理的C++笔记 —— vector常用方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。