【C++】vector的使用和模擬實現(超級詳解!!!!)

文章目錄

  • 前言
  • 1.vector的介紹及使用
    • 1.1 vector的介紹
    • 1.2 vector的使用
      • 1.2.1 vector的定義
      • 1.2.2 vector iterator 的使用
      • 1.2.3 vector 空間增長問題
      • 1.2.3 vector 增刪查改
      • 1.2.4 vector 迭代器失效問題。(重點!!!!!!)
      • 1.2.5 vector 在OJ中有關的練習題
  • 2.vector深度剖析及模擬實現
    • 2.1 std::vector的核心框架接口的模擬實現dzj::vector
  • 本文章內容后續會完善一些!!!
  • 總結


前言

提示:這里可以添加本文要記錄的大概內容:

C++中的vector是一個強大而靈活的動態數組容器,它提供了在運行時動態增長和收縮的能力,極大地簡化了數組的管理。vector是標準模板庫(STL)中的一部分,為程序員提供了高效的數據存儲和操作方式。在本博客中,我們將深入介紹vector的基本用法,并進行深度剖析和模擬實現,以幫助你更好地理解和利用這一重要的C++容器。


提示:以下是本篇文章正文內容,下面案例可供參考

1.vector的介紹及使用

1.1 vector的介紹

vector文檔介紹

vector是一個動態數組容器,它以模板類的形式實現,能夠存儲同一類型的元素。其最顯著的特點之一是能夠在運行時動態調整數組大小,而不需要手動管理內存。通過push_back()進行元素的追加、pop_back()進行末尾元素的刪除,以及使用迭代器進行元素的遍歷,vector提供了簡單而強大的操作方式。
vector的內部實現采用動態數組,這意味著它能夠在需要時自動分配更多的內存空間,以適應元素的增加。這種機制確保了vector的高效性,使得它適用于各種規模和類型的數據集。

參考文獻:
Josuttis, N. M. (2007). The C++ Standard Library: A Tutorial and Reference (2nd Edition). Addison-Wesley.
Stroustrup, B. (2013). The C++ Programming Language (4th Edition). Addison-Wesley.
Meyers, S. (2001). Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library. Addison-Wesley.

1.2 vector的使用

vector學習時一定要學會查看文檔:vector文檔介紹,vector在實際中非常的重要,在實際中我們熟悉常見的接口就可以,下面列出了哪些接口是要重點掌握的。

1.2.1 vector的定義

在這里插入圖片描述

#define _CRT_SECURE_NO_WARNINGS 1#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<int> v1;//無參構造v1.push_back(0);v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.push_back(5);v1.push_back(6);for (int i = 0; i < v1.size(); i++){cout << v1[i] << " ";}cout << endl;vector<int> v2(v1);v2.push_back(8);v2.push_back(8);v2.push_back(8);for (int i = 0; i < v2.size(); i++){cout << v2[i] << " ";}cout << endl;return 0;
}

1.2.2 vector iterator 的使用

在這里插入圖片描述
圖解:
在這里插入圖片描述

#include <iostream>
#include <vector>
using namespace std;
void Print1(const vector<int>&v)//正向遍歷
{vector<int>::const_iterator it = v.begin();while (it != v.end()){cout << *it << " ";it++;}cout << endl;
}
void Print2(const vector<int>& v)//反向遍歷
{vector<int>::const_reverse_iterator it = v.rbegin();while (it != v.rend()){cout << *it << " ";it++;}cout << endl;
}
int main()
{vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.push_back(5);v1.push_back(6);Print1(v1);Print2(v1);// 使用迭代器進行修改vector<int>::iterator it = v1.begin();while (it != v1.end()){*it *= 2;it++;}Print1(v1);Print2(v1);return 0;
}

1.2.3 vector 空間增長問題

在這里插入圖片描述

  1. capacity的代碼在vs和g++下分別運行會發現,vs下capacity是按1.5倍增長的,g++是按2倍增長的。
    這個問題經常會考察,不要固化的認為,順序表增容都是2倍,具體增長多少是根據具體的需求定義
    的。vs是PJ版本STL,g++是SGI版本STL。

  2. reserve只負責開辟空間,如果確定知道需要用多少空間,reserve可以緩解vector增容的代價缺陷問題。

  3. resize在開空間的同時還會進行初始化,影響size。


// vector::capacity
#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<int> v;cout << "making v growing!!!!" << endl;cout << "capacity changed:" << v.capacity() << endl;for (int i = 0; i < 100; i++){v.push_back(i);if (v.size() == v.capacity())cout << "capacity changed:" << v.capacity() << endl;}return 0;
}

運行結果:
在這里插入圖片描述

// vector::reserve
#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<int> v;for (int i = 0; i < 100; i++){v.push_back(i);}cout << "size:" << v.size()<<endl;cout << "capacity:" << v.capacity()<<endl;v.reserve(200);cout << "size:" << v.size() << endl;cout << "capacity:" << v.capacity() << endl;return 0;
}

運行結果:
在這里插入圖片描述

// vector::resize
#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<int> v;//for (int i = 0; i < 100; i++)//{//	v.push_back(i);//}cout << "size:" << v.size()<<endl;cout << "capacity:" << v.capacity()<<endl;v.resize(200);cout << "size:" << v.size() << endl;cout << "capacity:" << v.capacity() << endl;v.resize(100);cout << "size:" << v.size() << endl;cout << "capacity:" << v.capacity() << endl;v.resize(101,8);cout << "size:" << v.size() << endl;cout << "capacity:" << v.capacity() << endl;for (auto e : v){cout << e << " ";}return 0;
}

運行結果:
在這里插入圖片描述

1.2.3 vector 增刪查改

在這里插入圖片描述

// push_back/pop_back
#include <iostream>
#include <vector>
using namespace std;
int main()
{int arr[] = { 1,2,3,4 };vector<int> v(arr, arr + sizeof(arr) / sizeof(arr[0]));v.push_back(5);v.push_back(6);vector<int>::iterator it = v.begin();while (it != v.end()){cout << *it<<" ";it++;}cout << endl;v.pop_back();v.pop_back();it = v.begin();while (it != v.end()){cout << *it << " ";it++;}return 0;
}
// push_back/pop_back

運行結果:
在這里插入圖片描述

// find / insert / erase
#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);vector<int>::iterator pos = find(v.begin(), v.end(), 3);v.insert(pos, 0);for (auto e : v){cout << e << " ";}cout << endl;pos = find(v.begin(), v.end(), 3);v.erase(pos);for (auto e : v){cout << e << " ";}return 0;
}

運行結果:
在這里插入圖片描述

// operator[]+index 和 C++11中vector的新式for+auto的遍歷
// vector使用這兩種遍歷方式是比較便捷的。
#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<int> v = { 1,2,3,4 };//operator[]+indexfor (int i = 0; i < v.size(); i++){cout << v[i]<<" ";}cout << endl;for (int i = 0; i < v.size(); i++){v[i] *= 2;}vector<int> swapv;swapv.swap(v);for (auto e : swapv){cout << e << " ";}return 0;
}

運行結果:
在這里插入圖片描述

1.2.4 vector 迭代器失效問題。(重點!!!)

迭代器的主要作用就是讓算法能夠不用關心底層數據結構,其底層實際就是一個指針,或者是對指針進行了所謂的封裝,比如:vector的迭代器就是原生態指針T*。因此迭代器失效,實際就是迭代器底層對應指針所指向的空間被銷毀了,而使用一塊已經被釋放的空間,造成的后果是程序崩潰(即如果繼續使用已經失效的迭代器,程序可能會崩潰)。

對于vector可能會導致其迭代器失效的操作有

  1. 會引起其底層空間改變的操作,都有可能是迭代器失效,比如:resize、reserve、insert、assign、
    push_back等。
#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<int> v = { 1,2,3,4 };auto it = v.begin();while (it != v.end()){cout << *it << " ";++it;}v.reserve(100);while (it != v.end()){cout << *it << " ";++it;}return 0;
}

運行錯誤:
在這里插入圖片描述
出錯原因:以上操作,都有可能會導致vector擴容,也就是說vector底層原理舊空間被釋放掉,而在打印時,it還使用的是釋放之間的舊空間,在對it迭代器操作時,實際操作的是一塊已經被釋放的空間,而引起代碼運行時崩潰。
解決方式:在以上操作完成之后,如果想要繼續通過迭代器操作vector中的元素,只需給it重新賦值即可。

2. 指定位置元素的刪除操作–erase

#include <iostream>
using namespace std;
#include <vector>
int main()
{int a[] = { 1, 2, 3, 4 };vector<int> v(a, a + sizeof(a) / sizeof(int));// 使用find查找3所在位置的iteratorvector<int>::iterator pos = find(v.begin(), v.end(), 3);// 刪除pos位置的數據,導致pos迭代器失效。v.erase(pos);cout << *pos << endl; // 此處會導致非法訪問return 0;
}

erase刪除pos位置元素后,pos位置之后的元素會往前搬移,沒有導致底層空間的改變,理論上講迭代器不應該會失效,但是:如果pos剛好是最后一個元素,刪完之后pos剛好是end的位置,而end位置是沒有元素的,那么pos就失效了。因此刪除vector中任意位置上元素時,vs就認為該位置迭代器失效了。

迭代器失效解決辦法:在使用前,對迭代器重新賦值即可

1.2.5 vector 在OJ中有關的練習題

  1. 只出現一次的數字i
  2. 楊輝三角OJ
  3. 刪除排序數組中的重復項 OJ
  4. 只出現一次的數ii OJ
  5. 只出現一次的數iii OJ
  6. 數組中出現次數超過一半的數字 OJ
  7. 電話號碼字母組合OJ
  8. 連續子數組的最大和 OJ

2.vector深度剖析及模擬實現

在這里插入圖片描述

2.1 std::vector的核心框架接口的模擬實現dzj::vector

模擬實現代碼

本文章內容后續會完善一些!!!

總結

通過本文的閱讀,我們詳細了解了C++中vector的基本概念、使用方法和一些關鍵特性。從動態數組的角度深度剖析了vector的內部機制,以及通過模擬實現進一步加深了對其工作原理的理解。vector的靈活性和高效性使其成為C++編程中不可或缺的工具,無論是在簡單的數組操作還是復雜的數據結構中,都能展現其強大的應用價值。通過學習和研究vector,我們能夠更好地優化代碼、提高程序的效率,為C++編程帶來更多便利。希望本文對你在使用和理解C++中的vector時有所幫助。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/717249.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/717249.shtml
英文地址,請注明出處:http://en.pswp.cn/news/717249.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++入門和基礎

目錄 文章目錄 前言 一、C關鍵字 二、命名空間 2.1 命名空間的定義 2.2 命名空間的使用 2.3 標準命名空間 三、C輸入&輸出 四、缺省參數 4.1 缺省參數的概念 4.2 缺省參數的分類 五、函數重載 5.1 函數重載的簡介 5.2 函數重載的分類 六、引用 6.1 引用的…

搭建個人IC_EDA服務器(物理機)一:安裝Centos7

1.準備 大于8G的U盤&#xff1b;待裝的電腦&#xff0c;我使用淘汰的在大學時候使用的筆記本&#xff1b;U盤啟動器制作工具&#xff1a;UltralSo&#xff1b;官網下載的在沒有付費的情況下&#xff0c;即使試用期&#xff0c;安裝的時候會有莫名的問題&#xff0c;建議使用這…

【接口測試】常見HTTP面試題

目錄 HTTP GET 和 POST 的區別 GET 和 POST 方法都是安全和冪等的嗎 接口冪等實現方式 說說 post 請求的幾種參數格式是什么樣的&#xff1f; HTTP特性 HTTP&#xff08;1.1&#xff09; 的優點有哪些&#xff1f; HTTP&#xff08;1.1&#xff09; 的缺點有哪些&#x…

全量知識系統問題及SmartChat給出的答復 之14 解析器+DDD+文法型 之2

Q36. 知識系統中設計的三種文法解析器和設計模式之間的關系 進一步&#xff0c;我想將 知識系統中設計的三種語言&#xff08;形式語言、人工語言和自然&#xff09;的文法解析器和DDD中的三種程序類型&#xff08;領域模型、領域實體和領域服務&#xff09; 形式語言文法 我…

動態代理總結

Java 代理模式 使用代理對象來代替對真實對象(real object)的訪問&#xff0c;這樣就可以在不修改原目標對象的前提下&#xff0c;提供額外的功能操作&#xff0c;擴展目標對象的功能 靜態代理 靜態代理在編譯時就將接口、實現類、代理類這些都變成了一個個實際的 class 文件…

MQ如何防止消息被重復消費?

被詢問如何防止MQ消息被重復消費時&#xff0c;其實是在考察候選人對消息隊列、分布式系統設計以及容錯機制的理解&#xff0c;通過這些問題&#xff0c;可以全面了解候選人在處理MQ消息重復消費問題時的思考方式、技術能力和實踐經驗&#xff0c;從而評估其是否適合擔任相關崗…

Puzzles

題目鏈接&#xff1a;Submit - Codeforces?????? 解題思路&#xff1a; 題目大概意思就是在一個數組里找n個數里的最大值減最小值的最小值&#xff0c;先排序&#xff0c;然后將第i n - 1項減去第i項與最小值作比較&#xff0c;輸出最小值即可&#xff0c;注意循環結束…

NTP網絡校時服務器(GPS北斗衛星校時系統)應用場景

NTP網絡校時服務器&#xff08;GPS北斗衛星校時系統&#xff09;應用場景 NTP網絡校時服務器&#xff08;GPS北斗衛星校時系統&#xff09;應用場景 隨著大數據、云計算時代的到來,各行業信息化建設的不斷提升,信息化下的各個系統不再單獨處理各自業務,而是趨于協同工作,因此,各…

YOLOv應用開發與實現

一、背景與簡介 YOLO&#xff08;You Only Look Once&#xff09;是一種流行的實時目標檢測系統&#xff0c;其核心思想是將目標檢測視為回歸問題&#xff0c;從而可以在單個網絡中進行端到端的訓練。YOLOv作為該系列的最新版本&#xff0c;帶來了更高的檢測精度和更快的處理速…

代碼隨想錄day34||● 860.檸檬水找零 ● 406.根據身高重建隊列 ● 452. 用最少數量的箭引爆氣球

860. 檸檬水找零 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:bool lemonadeChange(vector<int>& bills) {int five0,ten0,twenty0;for(int bill:bills){if(bill5)five;if(bill10){if(five<0)return false;ten;five--;}if(bill20){if(ten&g…

【框架】MyBatis 框架重點解析

MyBatis 框架重點解析 1. MyBatis 執行流程 會話工廠生產的 SqlSession 對象提供了對數據庫執行SQL命令所需的所有方法&#xff0c;包括但不限于以下功能&#xff1a; 數據庫操作&#xff1a;SqlSession可以執行查詢&#xff08;select&#xff09;、插入&#xff08;insert&a…

騰訊云幻獸帕魯游戲存檔遷移教程,本地單人房遷移/四人世界怎么遷移存檔?

騰訊云幻獸帕魯游戲存檔遷移的方法主要包括以下幾個步驟&#xff1a; 登錄輕量云控制臺&#xff1a;首先&#xff0c;需要登錄到輕量云控制臺&#xff0c;這是進行存檔遷移的前提條件。在輕量云控制臺中&#xff0c;可以找到接收存檔的服務器卡片&#xff0c;并點擊進入實例詳情…

Jmeter 安裝

JMeter是Java的框架&#xff0c;因此在安裝Jmeter前需要先安裝JDK&#xff0c;此處安裝以Windows版為例 1. 安裝jdk&#xff1a;Java Downloads | Oracle 安裝完成后設置環境變量 將環境變量JAVA_HOME設置為 C:\Program Files\Java\jdk1.7.0_25 在系統變量Path中添加 C:\Pro…

股票技術指標(包含貪婪指數)

股票技術指標是用于分析股票價格和成交量數據&#xff0c;以便預測未來市場走勢的工具。技術分析師使用這些指標來識別市場趨勢、價格模式、交易信號和投資機會。技術指標通常基于數學公式&#xff0c;并通常在股票價格圖表上以圖形形式表示。 技術指標主要分為以下幾類&#x…

A Brief Introduction of the Tqdm Module in Python

DateAuthorVersionNote2024.02.28Dog TaoV1.0Release the note. 文章目錄 A Brief Introduction of the Tqdm Module in PythonIntroductionKey FeaturesInstallation Usage ExamplesBasic UsageAdvanced Usage A Brief Introduction of the Tqdm Module in Python Introducti…

力扣hot100:42.接雨水

什么時候能用雙指針&#xff1f; &#xff08;1&#xff09;對撞指針&#xff1a; ①兩數和問題中可以使用雙指針&#xff0c;先將兩數和升序排序&#xff0c;可以發現規律&#xff0c;如果當前兩數和大于target&#xff0c;則右指針向左走。 ②接雨水問題中&#xff0c;左邊最…

【算法集訓】基礎算法:枚舉

一、基本理解 枚舉的概念就是把滿足題目條件的所有情況都列舉出來&#xff0c;然后一一判定&#xff0c;找到最優解的過程。 枚舉雖然看起來麻煩&#xff0c;但是有時效率上比排序高&#xff0c;也是一個不錯的方法、 二、最值問題 1、兩個數的最值問題 兩個數的最小值&…

Vscode安裝,ssh插件與配置

原因 發現很多新人在練習linux&#xff0c;可是只有windows機的時候&#xff0c;一般都是下載虛擬機&#xff0c;然后在虛擬機上安裝ubuntu等linux平臺。每次需要在linux中寫代碼&#xff0c;就打開ubuntu&#xff0c;然后在終端上用vim寫代碼&#xff0c;或者先編輯代碼文本&…

css實現上下左右居中

css實現子盒子在父級盒子中上下左右居中 幾種常用的上下左右居中方式 HTML代碼部分 <div class"box"><img src"./img/77.jpeg" alt"" class"img"> </div>css部分 方式一 利用子絕父相和margin:auto實現 <sty…

內存管理 -----分段分頁

分段 分段&#xff1a;程序的分段地址空間&#xff0c;分段尋址方案 兩個問題 分段 &#xff1a;是更好分離和共享 左邊是有序的邏輯地址&#xff0c;右邊是無序的物理地址&#xff0c;然后需要有一種映射的關系&#xff08;段關聯機制&#xff09; 各個程序的分配相應的地址…