STL之vector容器

vector的介紹

1.vector是可變大小數組的容器

2.像數組一樣,采用連續的空間存儲,也就意味著可以通過下標去訪問,但它的大小可以動態改變

3.每次的插入都要開空間嗎?開空間就要意味著先開臨時空間,然后在拷貝舊的到新的上面,在釋放原來的,就時間而言,這是一個相對代價很高的任務;顯然這是不行的,vector的分配策略:會分配一些而外的空間以適應可能的增長,例如我們平時說的以1.5或者2倍的方式增容,不同的庫選擇不同的策略權衡空間的使用和重新分配,以至于在插入一個元素時能在常數時間內插入;

vector的使用

構造函數:

?

注意:這里的allocator_type是空間配置器,與內存池相關,可以暫時忽略

? ? ? ? ? 這里的vector<int>要傳模板,指明你每個元素里面存的類型是什么?

第一個能構造一個空的vector數組

第二個能構造4個元素,每個元素里面存100的數組

第三個傳迭代器能根據迭代器構造出一個對象

第四個是拷貝構造函數?

如果第二個中我沒有指定每個元素為100,它會根據你傳的模板是什么初始化為啥,例如你傳int就初始化為0

3種遍歷方式

1.operator[]

因為底層是數組,所以重載了operator[]方便遍歷

for(size_t i=0;i<vt.size();i++)
{cout<<vt[i]<<" ";
}

2.迭代器遍歷

?

?可以看到vector容器提供了begin/end和rbegin/rend,這說明我們可以正反向遍歷?

vector<int>::iterator it=vt.begin();
while(it!=vt.end())
{cout<<*it;it++;
}vector<int>::reverse_iterator rit=rbegin();
while(it!=rbegin())
{cout<<*it;it++;
}

3.返回for遍歷:底層就是迭代器,只要能實現迭代器就能實現范圍for

for(auto&e:vt)
{cout<<e;
}

注意:如果你有一個函數,例如打印函數,你是不想修改數組里面元素的值,那傳參時需要傳const修飾的數組,此時你在打印函數中使用迭代器,只能用const迭代器?

迭代器分兩個版本,一個是const迭代器一個是普通迭代器

void Print(const vector<int>&vt)
{vector<int>::const_iterator it=vt.begin();while(it!=vt.end())
{
cout<<*it;
*it+=1;//這句是錯的,你傳了const就意味著你不能通過迭代器去修改
}
}

?capacity函數接口

size():顧名思義就是返回數組的大小,這里的大小是有效元素的大小

capacity():是返回這里數組的容量,也就是你動態開辟出來的大小

empty():判斷是否為空;如果沒有元素即返回true,有就返回false

resize():改變數組的size

reserve():改變數組的容量,如果提前知道空間可以減少增容的代價

注意:vs2022是以1.5倍增長,gcc是以兩倍增長,兩個用的STL版本不一樣,vs使用PJ版本,gcc是用SGI版本

Modifiers函數接口

數組當然實現的是尾插和尾刪,效率高,如果你有頭插和頭刪最好別選vector(后面會介紹list和vector的優缺點)

push_back():尾插一個數據

pop_back():尾刪一個數據

insert():任意位置的插入,在pos位置之前插入

注意:這里傳迭代器?

erase():任意位置的刪除,刪除pos位置的元素,返回下一個元素的迭代器

注意:這里我們不知道要刪除的元素的位置該如何找到呢?vector沒有實現find

可以調用<algorithm>庫實現的find

找到返回pos位置的迭代器,找不到返回end();

?swap():交換兩個vector的數據空間

clear():清空元素,但開辟的空間沒有釋放

?重點談迭代器失效問題

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

第一種情況:

如果你先定義了迭代器vector<int>::iterator it=vt.begin();

然后在進行各種擴容操作reserve,resize,insert,assign,push_back等

然后在使用迭代器,那原來的指針it指向的的那塊空間已經被釋放了,因為你進行了擴容開辟了新空間,你在使用迭代器去解引用或者it!=vt.end()等操作都可能會造成程序崩潰

第二種情況:

比如你使用庫實現的find去查找某個元素,會返回一個迭代器類型,然后在釋放這個位置的元素

vector<int>::iterator pos=find(vt.begin(),vt.end(),3);
if(pos!=vt.end())
{erase(pos);
}
cout<<*pos<<;//此處會導致非法訪問

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

動態二維數組的理解:

我們如何創建一個二維數組,可以想象每個vector的元素都是一個vector<int>

vector<vector<int>> vv(5);

這里可以想象一個一維數組,有五個元素,每個元素都是一個vector<int>?

那我們如何初始化呢?

?第一種:我們學過vector<int> v(3,5)//這是創建3個元素,每個元素都是5,因此我們可以這與初始化二維數組,rows是行,每個元素是vector<int>(cols),initial)

int main() {// 定義二維數組的行數和列數int rows = 3;int cols = 4;// 初始值int initialValue = 0;// 創建并初始化二維 vectorstd::vector<std::vector<int>> twoDArray(rows, std::vector<int>(cols, initialValue));// 輸出二維數組for (const auto& row : twoDArray) {for (int element : row) {std::cout << element << " ";}std::cout << std::endl;}return 0;
}

第二種:

可以創建好二維數組,在用循環依次填入數據?


int main() {// 定義二維數組的行數和列數int rows = 3;int cols = 4;// 初始值int initialValue = 0;// 創建空的二維 vectorstd::vector<std::vector<int>> twoDArray;// 逐行添加元素for (int i = 0; i < rows; ++i) {std::vector<int> row(cols, initialValue);twoDArray.push_back(row);}// 輸出二維數組for (const auto& row : twoDArray) {for (int element : row) {std::cout << element << " ";}std::cout << std::endl;}return 0;
}

?第三種:使用c++11的初始化列表進行初始化

int main() {// 使用列表初始化創建二維 vectorstd::vector<std::vector<int>> twoDArray = {{1, 2, 3},{4, 5, 6},{7, 8, 9}};// 輸出二維數組for (const auto& row : twoDArray) {for (int element : row) {std::cout << element << " ";}std::cout << std::endl;}return 0;
}

注意:當我們創建好了之后,可以像一個二維數組一樣使用vv[i][j]去訪問每個元素

實質就是operator[]重載運算符,第一個[]先和vv結合,第二個后結合就可以訪問了?

?簡單模擬實現vector容器、

我已經把代碼上傳gitee,有需要可以自己拿

?June: 這里包含我的c++和Linux及數據結構https://gitee.com/taifanshu/day2.git

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

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

相關文章

[學成在線]22-自動部署項目

自動部署 實戰流程 下邊使用jenkins實現CI/CD的流程。 1、將代碼使用Git托管 2、在jenkins創建任務&#xff0c;從Git拉取代碼。 3、拉取代碼后進行自動構建&#xff1a;測試、打包、部署。 首先將代碼打成鏡像包上傳到docker私服。 自動創建容器、啟動容器。 4、當有代…

74HC123的電路應用場景

74HC123的電路應用場景 **1. 引腳功能示例****2. 核心功能****&#xff08;1&#xff09;單穩態觸發器****&#xff08;2&#xff09;雙獨立通道****&#xff08;3&#xff09;靈活觸發方式** **3. 工作原理****4. 典型應用場景****&#xff08;1&#xff09;定時與延時控制***…

【人工智能】大模型安全的深度剖析:DeepSeek漏洞分析與防護實踐

《Python OpenCV從菜鳥到高手》帶你進入圖像處理與計算機視覺的大門! 解鎖Python編程的無限可能:《奇妙的Python》帶你漫游代碼世界 隨著大語言模型(LLM)的廣泛應用,其安全性問題日益凸顯。DeepSeek作為中國領先的開源AI模型,以低成本和高性能著稱,但近期暴露的數據庫…

《ESP32音頻開發實戰:I2S協議解析與WAV音頻錄制/播放全指南》

前言 在智能硬件和物聯網應用中&#xff0c;音頻處理能力正成為越來越重要的功能——無論是語音交互、環境音采集&#xff0c;還是音樂播放&#xff0c;都離不開高效的音頻數據傳輸與處理。而I2S&#xff08;Inter-IC Sound&#xff09;作為專為音頻設計的通信協議&#xff0c…

大數據實時數倉的數據質量監控解決方案

實時數倉不僅僅是傳統數據倉庫的升級版,它更強調數據的實時性、流動性和高可用性,通過對海量數據的即時處理和分析,為企業提供近乎實時的洞察力。這種能力在金融、零售、制造、互聯網等行業中尤為關鍵,例如,電商平臺可以通過實時數倉監控用戶行為,動態調整推薦算法;金融…

56認知干貨:智能化產業

如果在不久的未來,一座高樓大廈的建設,只需將圖紙輸入系統,無數臺機器人就能精準協作完成任務; 電影節的主角不再是人類,動漫與影視作品將不再需要人類創作; 當播種和收獲的工作無人參與,所有過程都能自動化進行; 這將預示著我們將迎來一個智能化社會,在這個社會中,…

使用synchronized關鍵字同步Java線程

問題 在Java多線程編程中&#xff0c;你需要保護某些數據&#xff0c;防止多個線程同時訪問導致數據不一致或程序錯誤。 解決方案 在需要保護的方法或代碼段上使用synchronized關鍵字。 討論 synchronized關鍵字是Java提供的同步機制&#xff0c;用于確保在同一時刻只有一…

MATLAB基于格拉姆角場與2DCNN-BiGRU的軸承故障診斷模型

本博客來源于CSDN機器魚&#xff0c;未同意任何人轉載。 更多內容&#xff0c;歡迎點擊本專欄目錄&#xff0c;查看更多內容。 目錄 0 引言 1 格拉姆角場原理 2 2DCNN-BiGRU網絡結構 3 應用實例 3.1 數據準備 3.2 格拉姆角場數據提取 3.3 網絡模型搭建-重中之重 3.4 …

電氣設備器件選型參數---斷路器

斷路器 一、基本電氣參數 額定電壓&#xff08;Ue&#xff09; 必須≥系統最高工作電壓&#xff08;如380V、660V等&#xff09;。 注意直流/交流系統的區別&#xff0c;直流斷路器需專門設計。 額定電流&#xff08;In&#xff09; 根據負載的持續工作電流選擇&#xff0c;…

Linux常用命令30——groupadd創建新的用戶組

在使用Linux或macOS日常開發中&#xff0c;熟悉一些基本的命令有助于提高工作效率&#xff0c;groupadd命令的功能是創建新的用戶組。每個用戶在創建時都有一個與其同名的基本組&#xff0c;后期可以使用groupadd命令創建出新的用戶組信息&#xff0c;讓多個用戶加入指定的擴展…

微信小程序 自定義組件 標簽管理

環境 小程序環境&#xff1a; 微信開發者工具&#xff1a;RC 1.06.2503281 win32-x64 基礎運行庫&#xff1a;3.8.1 概述 基礎功能 標簽增刪改查&#xff1a;支持添加/刪除單個標簽、批量刪除、重置默認標簽 數據展示&#xff1a;通過對話框展示結構化數據并支持復制 動…

wpf CommandParameter 傳遞MouseWheelEventArgs參數 ,用 MvvmLight 實現

在 WPF 中使用 MVVM Light 框架傳遞 MouseWheelEventArgs 參數至 CommandParameter,可通過以下步驟實現: ?1. XAML 中配置事件綁定? 在控件上通過 EventToCommand 綁定鼠標滾輪事件,并啟用 PassEventArgsToCommand 屬性以傳遞事件參數: <!-- 命名空間聲明 --> x…

vmware diffy配置ollama 本機ip無法訪問

防火墻直接關閉 本地測試&#xff0c;給它直接關了 ollama配置 vim /etc/systemd/system/ollama.service這是的配置 [Unit] DescriptionOllama Service Afternetwork-online.target[Service] Environment"OLLAMA_HOST0.0.0.0:11434" #Environment"OLLAMA_OR…

React--》掌握react構建拖拽交互的技巧

在這篇文章中將深入探討如何使用react-dnd&#xff0c;從基礎的拖拽操作到更復雜的自定義功能帶你一步步走向實現流暢、可控且用戶友好的拖拽體驗,無論你是剛接觸拖拽功能的初學者還是想要精細化拖拽交互的經驗開發者&#xff0c;都能從中找到適合自己的靈感和解決方案。 目錄 …

數據結構與算法:回溯

回溯 先給出一些leetcode算法題&#xff0c;以后遇見了相關題目再往上增加 主要參考代碼隨想錄 2.1、組合問題 關于去重&#xff1a;兩種寫法的性能分析 需要注意的是&#xff1a;使用set去重的版本相對于used數組的版本效率都要低很多&#xff0c;大家在leetcode上提交&#x…

iview 分頁改變每頁條數時請求兩次問題

問題 在iview page分頁的時候&#xff0c;修改每頁條數時&#xff0c;會發出兩次請求。 iview 版本是4.0.0 原因 iview 的分頁在調用on-page-size-change之前會調用on-Change。默認會先調用on-Change回到第一頁&#xff0c;再調用on-page-size-change改變分頁顯示數量 此時就會…

一周學會Pandas2 Python數據處理與分析-Pandas2復雜數據查詢操作

鋒哥原創的Pandas2 Python數據處理與分析 視頻教程&#xff1a; 2025版 Pandas2 Python數據處理與分析 視頻教程(無廢話版) 玩命更新中~_嗶哩嗶哩_bilibili 前面我們學了.loc[]等幾個簡單的數據篩選操作&#xff0c;但實際業務需求往 往需要按照一定的條件甚至復雜的組合條件…

【Vue bug】:deep()失效

vue 組件中使用了 element-plus 組件 <template><el-dialog:model-value"visible":title"title":width"width px":before-close"onClose"><div class"container" :style"{height:height px}"&g…

Trae 安裝第三方插件支持本地部署的大語言模型

Trae 安裝第三方插件支持本地部署的大語言模型 0. 引言1. 安裝插件 0. 引言 字節發布的 Trae IDE 一直不支持本地部署的的大語言模型。 Qwen3 剛剛發布&#xff0c;想在 Trae 中使用本地部署的 Qwen3&#xff0c;我們可以在 Trae 中安裝其他插件。 1. 安裝插件 我們可以安裝…

JavaScript 中的 Proxy 與 Reflect 教程

目錄 get 和 set 捕獲器詳解 為什么要用 Reflect? 使用語法間接調用內部方法 使用 Reflect 直接調用內部方法 對比總結: Reflect API 及其與 Proxy 的配合 Proxy 的典型應用場景 Proxy 是 ES6 引入的一種元編程特性。它允許創建一個代理對象來包裝目標對象,并攔截對目標…