亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

c++中容器之總結篇

2020-01-26 15:00:40
字體:
來源:轉載
供稿:網友

C++中的容器大致可以分為兩個大類:順序容器和關聯容器。順序容器中有包含有順序容器適配器。
順序容器:將單一類型元素聚集起來成為容器,然后根據位置來存儲和訪問這些元素。主要有vector、list、deque(雙端隊列)。順序容器適配器:stack、queue和priority_queue。
關聯容器:支持通過鍵來高效地查找和讀取元素。主要有:pair、set、map、multiset和multimap。
接下來依次對于各種容器做詳細的介紹。

一、順序容器

1、順序容器定義
為了定義一個容器類型的對象,必須先包含相關的頭文件:
      定義vector:#include <vector>
      定義list:#include <list>
      定義deque:#include <deque>

定義示例

vector<int> vi;list<int> li;deque<int> di;

2、順序容器初始化

初始化示例:

//初始化為一個容器的副本vector<int> vi;vector<int> vi2(vi); //利用vi來初始化vi2//初始化為一段元素的副本char*words[] = {"stately", "plump", "buck", "mulligan"};size_twords_size = sizeof(words)/sizeof(char*);list<string> words2(words, words + words_size);//分配和初始化指定數目的元素constlist<int>::size_type list_size = 64;list<string> slist(list_size, "a"); // 64 strings, each is a

3、順序容器支持的指針運算

①所有順序都支持的指針運行

②vector 和 deque 容器的迭代器提供額外的運算

③迭代器失效:一些容器操作會修改容器的內在狀態或移動容器內的元素。這樣的操作使所有指向被移動的元素的迭代器失效,也可能同時使其他迭代器失效。使用無效迭代器是沒有定義的,可能會導致與懸垂指針相同的問題。

④begin和end成員:begin和end操作產生指向容器內第一個元素和最后一個元素的下一位置的迭代器。

3、順序容器操作

①添加元素

添加元素示例:

//在容器首部或者尾部添加數據list<int> ilist;ilist.push_back(ix);//尾部添加ilist.push_front(ix);//首部添加//在容器中指定位置添加元素list<string> lst;list<string>::iterator iter = lst.begin();while (cin >> word)iter = lst.insert(iter, word); // 和push_front意義一樣//插入一段元素list<string> slist;string sarray[4] = {"quasi", "simba", "frollo", "scar"};slist.insert(slist.end(), 10, "A");//尾部前添加十個元素都是Alist<string>::iterator slist_iter = slist.begin();slist.insert(slist_iter, sarray+2, sarray+4);//指針范圍添加

②容器大小的操作

示例:

list<int> ilist(10, 1);ilist.resize(15); // 尾部添加五個元素,值都為0ilist.resize(25, -1); // 再在尾部添加十個元素,元素為-1ilist.resize(5); // 從尾部刪除20個元素

③訪問元素

int vector<int> vi;for(int i=0;i<10;i++)vi.push_back(i);cout<<vi[0]<<endl;cout<<vi.at(0)<<endl;cout<<vi[10]<<endl; //越界錯誤cout<<vi.at(10)<<endl;//越界錯誤

④刪除元素

示例:

//刪除第一個或最后一個元素list<int> li;for(int i=0;i<10;i++)list.push_back(i);li.pop_front();//刪除第一個元素li.pop_back(); //刪除最后一個元素//刪除容器內的一個元素list<int>::iterator iter =li.begin();if(iter!= li.end())li.erase(iter);//刪除容器內所有元素li.clear();

⑤賦值與swap

list<string> sl1,sl2;for(int i=0;i<10;i++)sl2.push_back("a");sl1.assign(sl2.begin(),sl2.end());//用sl2的指針范圍賦值,sl1中十個元素都為asl1.assign(10, "A"); //s1被重新賦值,擁有十個元素,都為A

swap示例:

vector<string> vs1(3); // vs1有3個元素
vector<string> vs(5); // vs2有5個元素
vs1.swap(vs2);//執行后,vs1中5個元素,而vs2則存3個元素。

⑥vector的自增長:capacity 和 reserve 成員

為了提高vector的效率,不用每次添加元素都重新分配空間。vector會在分配空間時候預分配大于需要的空間。vector 類提供了兩個成員函數:capacity 和reserve 使程序員可與 vector 容器內存分配的實現部分交互工作。
capacity操作:獲取在容器需要分配更多的存儲空間之前能夠存儲的元素總數
reserve操作:告訴vector容器應該預留多少個元素的存儲空間

capacity(容量)與size(長度)的區別:size指容器當前擁有的元素個數,而capacity則指容器在必須分配新存儲空間之前可以存儲的元素總數。capacity是比size大的一般情況下。
示例:

vector<int> ivec;cout << "ivec: size: " << ivec.size()<< " capacity: " << ivec.capacity() << endl;//都為0for (vector<int>::size_type ix = 0; ix != 24; ++ix)ivec.push_back(ix);cout << "ivec: size: " << ivec.size()<< " capacity: " << ivec.capacity() << endl;//capacity大于size

可以通過函數reserve()來操作預留空間

//在之前一段代碼的基礎上
ivec.reserve(ivec.capacity()+50);//為ivec增加了50的預留空間

另外:如果不手動操作來預留空間,每當 vector 容器不得不分配新的存儲空間時,以加倍當前容量的分配策略實現重新分配。

4、容器的選用
選擇容器類型的常規法則:
①如果程序要求隨機訪問元素,則應使用 vector 或 deque 容器。
②如果程序必須在容器的中間位置插入或刪除元素,則應采用 list 容器。
③如果程序不是在容器的中間位置,而是在容器首部或尾部插入或刪除元素,則應采用 deque 容器。
④如果只需在讀取輸入時在容器的中間位置插入元素,然后需要隨機訪問元素,則可考慮在輸入時將元素讀入到一個 list 容器,接著對此容器重新排序,使其適合順序訪問,然后將排序后的 list 容器復制到一個 vector容器。
如果程序既需要隨機訪問又必須在容器的中間位置插入或刪除元素,選擇何種容器取決于下面兩種操作付出的相對代價:隨機訪問 list 容器元素的代價,以及在 vector 或 deque 容器中插入/刪除元素時復制元素的代價。通常來說,應用中占優勢的操作(程序中更多使用的是訪問操作還是插入/刪除操作)將決定應該什么類型的容器。

5、容器適配器

①適配器通用的操作和類型

②適配器的初始化
所有適配器都定義了兩個構造函數:默認構造函數用于創建空對象,而帶一個容器參數的構造函數將參數容器的副本作為其基礎值。

默認的stack和queue都基于deque容器實現,而priority_queue則在vector容器上實現。
示例:

vector<int> vi;deque<int> deq;stack<int> stk(deq); //用deq初始化stkstack<int> stk1(vi); //報錯

③適配器的操作
棧適配器:

隊列和優先級隊列:

二、關聯容器

1、pair

①pairs類型提供的操作

②pairs類型定義和初始化

pair<string, string> test("A", "B");

③pairs其他操作

//pairs對象的操作string firstBook;if (author.first == "James" && author.second == "Joyce")firstBook = "Stephen Hero";//生成新的pair對象pair<string, string> next_auth;next_auth = make_pair("A","B");//第一種方法next_auth = pair<string, string>("A","B"); //第二種方法cin>>next_auth.first>>next_auth.second;//第三種方法

2、map

map 是鍵-值對的集合。map 類型通常可理解為關聯數組:可使用鍵作為下標來獲取一個值,正如內置數組類型一樣。而關聯的本質在于元素的值與某個特定的鍵相關聯,而并非通過元素在數組中的位置來獲取。

①map對象的定義

map<string, int> word_count;

這個語句定義了一個名為 word_count 的 map 對象,由 string 類型的鍵索引,關聯的值則int型。
map訪問:對迭代器進行解引用時,將獲得一個引用,指向容器中一個pair<const string,int>類
型的值。通過pair類型的訪問方式進行訪問。

②map的構造函數

③鍵類型的約束
在使用關聯容器時,它的鍵不但有一個類型,而且還有一個相關的比較函數。所用的比較函數必須在鍵類型上定義嚴格弱排序(strict weak ordering):可理解為鍵類型數據上的“小于”關系,雖然實際上可以選擇將比較函數設計得更復雜。
對于鍵類型,唯一的約束就是必須支持 < 操作符,至于是否支持其他的關系或相等運算,則不作要求。

④map類定義的類型

value_type是存儲元素的鍵以及值的pair類型,而且鍵為const。例如,word_count 數組的value_type 為pair<const string,int> 類型。value_type 是 pair 類型,它的值成員可以修改,但鍵成員不能修改。

⑤map添加元素
添加元素有兩種方法:1、先用下標操作符獲取元素,然后給獲取的元素賦值 2、使用insert成員函數實現
下標操作添加元素:如果該鍵已在容器中,則 map 的下標運算與 vector 的下標運算行為相同:返回該鍵所關聯的值。只有在所查找的鍵不存在時,map 容器才為該鍵創建一個新的元素,并將它插入到此 map 對象中。此時,所關聯的值采用值初始化:類類型的元素用默認構造函數初始化,而內置類型的元素初始化為 0。
insert 操作:

示例:

word_count.insert(map<string, int>::value_type("Anna", 1));word_count.insert(make_pair("Anna", 1));

insert的返回值:包含一個迭代器和一個bool值的pair對象,其中迭代器指向map中具有相應鍵的元素,而bool值則表示是否插入了該元素。如果該鍵已在容器中,則其關聯的值保持不變,返回的bool值為true。在這兩種情況下,迭代器都將指向具有給定鍵的元素。

pair<map<string, int>::iterator, bool> ret =
word_count.insert(make_pair(word, 1));

ret存儲insert函數返回的pair對象。該pair的first成員是一個map迭代器,指向插入的鍵。ret.first從insert返回的pair對象中獲取 map 迭代器;ret.second從insert返回是否插入了該元素。

⑥查找并讀取map中的元素
map中使用下標存在一個很危險的副作用:如果該鍵不在 map 容器中,那么下標操作會插入一個具有該鍵的新元素。所以map 容器提供了兩個操作:count 和 find,用于檢查某個鍵是否存在而不會插入該鍵。

int occurs = 0;if (word_count.count("foobar"))occurs = word_count["foobar"];map<string,int>::iterator it = word_count.find("foobar");if (it != word_count.end())occurs = it->second;

⑦從map對象中刪除元素

string removal_word = "a";if (word_count.erase(removal_word))cout << "ok: " << removal_word << " removed/n";else cout << "oops: " << removal_word << " not found!/n";

3、set

①set容器的定義和使用
set 容器的每個鍵都只能對應一個元素。以一段范圍的元素初始化set對象,或在set對象中插入一組元素時,對于每個鍵,事實上都只添加了一個元素。

vector<int> ivec;for (vector<int>::size_type i = 0; i != 10; ++i) {ivec.push_back(i);ivec.push_back(i);}set<int> iset(ivec.begin(), ivec.end());cout << ivec.size() << endl; //20個cout << iset.size() << endl; // 10個

②在set中添加元素

set<string> set1;set1.insert("the"); //第一種方法:直接添加set<int> iset2;iset2.insert(ivec.begin(), ivec.end());//第二中方法:通過指針迭代器

③從set中獲取元素
set 容器不提供下標操作符。為了通過鍵從 set 中獲取元素,可使用 find運算。如果只需簡單地判斷某個元素是否存在,同樣可以使用 count 運算,返回 set 中該鍵對應的元素個數。當然,對于 set 容器,count 的返回值只能是1(該元素存在)或 0(該元素不存在)

set<int> iset;for(int i = 0; i<10; i++)iset.insert(i);iset.find(1) // 返回指向元素內容為1的指針iset.find(11) // 返回指針iset.end()iset.count(1) // 存在,返回1iset.count(11) // 不存在,返回0

3、multimap 和 multiset
關聯容器 map 和 set 的元素是按順序存儲的。而 multimap 和multset 也一樣。因此,在multimap和multiset容器中,如果某個鍵對應多個實例,則這些實例在容器中將相鄰存放。迭代遍歷multimap或multiset容器時,可保證依次返回特定鍵所關聯的所有元素。

①迭代器的關聯容器操作

以上就是本文的全部內容,希望對大家的學習有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品久久久久久久久久久久久久| 亚洲va久久久噜噜噜久久天堂| 久久久999国产| 精品露脸国产偷人在视频| 精品无人区太爽高潮在线播放| 欧美日韩在线视频首页| 精品国产一区二区在线| 久久久久久成人精品| 欧美电影在线播放| 成人国产精品一区二区| 午夜精品一区二区三区在线视频| 欧美二区乱c黑人| 性视频1819p久久| 黑人极品videos精品欧美裸| 色爱av美腿丝袜综合粉嫩av| 亚洲人成绝费网站色www| 欧美另类暴力丝袜| 91精品久久久久久久久久另类| 久久亚洲成人精品| 亚洲黄页视频免费观看| 91精品视频专区| 国产视频亚洲视频| 亚洲已满18点击进入在线看片| 日韩在线观看av| 久久精品精品电影网| 一区二区三区在线播放欧美| 日韩欧美中文免费| 狠狠躁夜夜躁人人爽天天天天97| 欧美在线视频播放| 欧美电影《睫毛膏》| 日韩在线一区二区三区免费视频| 久久久精品欧美| 欧美精品18videos性欧| 久久精品99国产精品酒店日本| 国产一区二区三区精品久久久| 久久精品电影一区二区| 69久久夜色精品国产69乱青草| 日韩欧美福利视频| 日韩在线视频网| 亚洲va欧美va国产综合久久| xxx欧美精品| 欧美视频免费在线观看| 狠狠躁天天躁日日躁欧美| 日韩av不卡在线| 日本精品性网站在线观看| 中文字幕亚洲欧美日韩在线不卡| 91中文精品字幕在线视频| 亚洲精品一区二区久| 国产精品视频网站| 26uuu另类亚洲欧美日本老年| 欧美中在线观看| 日韩电影免费观看在线观看| 亚洲va久久久噜噜噜久久天堂| 国产精品久久二区| 精品国产福利视频| 久久久成人的性感天堂| 日产日韩在线亚洲欧美| 久久精品在线视频| 亚洲free性xxxx护士hd| 国产精品久久久久久影视| 日韩av免费看网站| 91久久久久久久久久久久久| 国模精品一区二区三区色天香| 欧美性高潮床叫视频| 日韩欧美中文在线| 久久精品国产一区二区电影| 久久91亚洲精品中文字幕| 欧美中文字幕在线播放| 97欧美精品一区二区三区| 在线观看日韩www视频免费| 亚洲视频在线免费观看| 成人免费淫片视频软件| 成人免费午夜电影| 久久99久久久久久久噜噜| 日韩成人中文电影| 91在线视频九色| 久久亚洲国产精品成人av秋霞| 久久韩国免费视频| 成人欧美一区二区三区在线湿哒哒| 欧美日韩在线第一页| 日韩精品丝袜在线| 久久精品成人一区二区三区| 91精品中文在线| 亚洲欧美国产一区二区三区| 国产精品入口夜色视频大尺度| 中文字幕自拍vr一区二区三区| 中国日韩欧美久久久久久久久| 亚洲少妇激情视频| 欧美影院成年免费版| 日韩性生活视频| 欧美激情2020午夜免费观看| 欧美日韩激情视频| 成人精品在线观看| 日本亚洲欧美成人| 久久精品国亚洲| 精品国产一区二区三区久久狼黑人| 国产精品成人免费视频| 伊人成人开心激情综合网| 精品国产依人香蕉在线精品| 国产精品久久久久久久久久东京| 久久国产精品影视| 国产97人人超碰caoprom| 欧美成人亚洲成人日韩成人| 欧美精品久久久久a| 亚洲国内精品视频| 色婷婷av一区二区三区在线观看| 日韩欧美在线视频| 日韩高清av在线| 欧美激情一区二区三区久久久| 久久亚洲欧美日韩精品专区| 中文字幕九色91在线| 亚洲天堂av女优| 精品亚洲一区二区三区| 欧美日韩亚洲系列| 亚洲精品免费在线视频| 亚洲欧洲日产国码av系列天堂| 精品久久久久久中文字幕| 这里只有精品丝袜| 久久综合伊人77777尤物| 亚洲美女av在线播放| 亚洲欧美日韩天堂| 91夜夜揉人人捏人人添红杏| 国内免费久久久久久久久久久| 精品国产一区二区三区久久狼黑人| 一个人看的www欧美| 成人h视频在线观看播放| 亚洲欧美制服中文字幕| 精品日韩视频在线观看| 欧美激情视频播放| 91av免费观看91av精品在线| 亚洲午夜激情免费视频| 在线成人激情视频| 狠狠躁夜夜躁人人躁婷婷91| 欧美激情va永久在线播放| 欧美最顶级丰满的aⅴ艳星| 亚洲a级在线观看| 日韩电影中文 亚洲精品乱码| 欧美极度另类性三渗透| 亚洲国产精品成人va在线观看| 欧美日韩激情美女| 日韩精品日韩在线观看| 国产精品极品美女在线观看免费| 2023亚洲男人天堂| 日韩电影免费观看在线观看| 狠狠躁天天躁日日躁欧美| 91色视频在线观看| 国产免费一区二区三区香蕉精| 精品中文字幕视频| 欧美黄色片视频| 国产在线观看不卡| 在线看国产精品| 国产精品看片资源| 国产精品色午夜在线观看| 中文字幕欧美日韩在线| 欧美成人sm免费视频| 欧洲亚洲免费在线| 久精品免费视频| 国产精品白丝jk喷水视频一区| 欧美xxxx18性欧美| 91精品国产高清久久久久久91| 亚洲欧美日韩中文在线制服| 亚洲免费高清视频| 精品久久久久久中文字幕大豆网| 欧美国产日韩一区二区在线观看|