日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

【C/C++学习】之STL详解

發(fā)布時(shí)間:2024/3/13 c/c++ 88 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【C/C++学习】之STL详解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

概述

STL六大組件簡介

三大組件介紹

  • 容器

  • 算法

  • 迭代器

  • 常用容器

    ? ?1. string容器

    ? ? ? ? ??string容器基本概念
    ? ? ? ? ? string容器常用操作

    ? ?2. vector容器

    ? ? ? ? ??vector容器基本概念
    ? ? ? ? ? vector迭代器
    ? ? ? ? ? vector的數(shù)據(jù)結(jié)構(gòu)
    ? ? ? ? ? vector常用API操作

    ? ?3. deque容器

    ? ? ? ? ? deque容器基本概念
    ? ? ? ? ? deque容器實(shí)現(xiàn)原理
    ? ? ? ? ? deque常用API

    ? ?4. stack容器

    ? ? ? ? ? stack容器基本概念
    ? ? ? ? ? stack沒有迭代器
    ? ? ? ? ? stack常用API

    ? ?5. queue容器

    ? ? ? ? ? queue容器基本概念
    ? ? ? ? ? queue沒有迭代器
    ? ? ? ? ? queue常用API

    ? ?6. list容器

    ? ? ? ? ? list容器的迭代器
    ? ? ? ? ? list容器的數(shù)據(jù)結(jié)構(gòu)
    ? ? ? ? ? list常用API

    ? ?7. set/multiset容器

    ? ? ? ? ? set容器基本概念
    ? ? ? ? ? multiset容器基本概念
    ? ? ? ? ? set常用API
    ? ? ? ? ? 對組(pair)

    ? ?8. map/multimap容器

    ? ? ? ? ? map/multimap基本概念
    ? ? ? ? ? map/multimap常用API

    STL容器使用時(shí)機(jī)

    常用算法

    ? ?1. 函數(shù)對象
    ? ?2. 謂詞
    ? ?3.內(nèi)建函數(shù)對象
    ? ?4. 函數(shù)對象適配器

    算法概述

    ? ?1. 常用遍歷算法
    ? ?2. 常用查找算法
    ? ?3. 常用排序算法
    ? ?4. 常用拷貝和替換算法
    ? ?5. 常用算數(shù)生成算法
    ? ?6. 常用集合算法

    概述

    長久以來,軟件界一直希望建立一種可重復(fù)利用的東西,以及一種得以制造出”可重復(fù)運(yùn)用的東西”的方法,從函數(shù)(functions),類別(classes),函數(shù)庫(function libraries),類別庫(class libraries)、各種組件,從模塊化設(shè)計(jì),到面向?qū)ο?object oriented ),為的就是復(fù)用性的提升。

    復(fù)用性必須建立在某種標(biāo)準(zhǔn)之上。但是在許多環(huán)境下,就連軟件開發(fā)最基本的數(shù)據(jù)結(jié)構(gòu)(data structures) 和算法(algorithm)都未能有一套標(biāo)準(zhǔn)。大量程序員被迫從事大量重復(fù)的工作,竟然是為了完成前人已經(jīng)完成而自己手上并未擁有的程序代碼,這不僅是人力資源的浪費(fèi),也是挫折與痛苦的來源。

    為了建立數(shù)據(jù)結(jié)構(gòu)和算法的一套標(biāo)準(zhǔn),并且降低他們之間的耦合關(guān)系,以提升各自的獨(dú)立性、彈性、交互操作性(相互合作性,interoperability),誕生了STL。

    STL(Standard Template Library,標(biāo)準(zhǔn)模板庫),是惠普實(shí)驗(yàn)室開發(fā)的一系列軟件的統(tǒng)稱?,F(xiàn)在主要出現(xiàn)在 c++中,但是在引入 c++之前該技術(shù)已經(jīng)存在很長時(shí)間了。

    STL 從廣義上分為: 容器(container) 算法(algorithm) 迭代器(iterator)。

    容器和算法之間通過迭代器進(jìn)行無縫連接。STL 幾乎所有的代碼都采用了模板類或者模板函數(shù),這相比傳統(tǒng)的由函數(shù)和類組成的庫來說提供了更好的代碼重用機(jī)會。

    STL(Standard Template Library)標(biāo)準(zhǔn)模板庫,在我們 c++標(biāo)準(zhǔn)程序庫中隸屬于 STL 的占到了 80%以上。


    STL六大組件簡介

    STL提供了六大組件,彼此之間可以組合套用,這六大組件分別是:容器、算法、迭代器、仿函數(shù)、適配器(配接器)、空間配置器。

    容器:各種數(shù)據(jù)結(jié)構(gòu),如vector、list、deque、set、map等,用來存放數(shù)據(jù),從實(shí)現(xiàn)角度來看,STL容器是一種class template。

    算法:各種常用的算法,如sort、find、copy、for_each。從實(shí)現(xiàn)的角度來看,STL算法是一種function tempalte.

    迭代器:扮演了容器與算法之間的膠合劑,共有五種類型,從實(shí)現(xiàn)角度來看,迭代器是一種將operator* , operator-> , operator++,operator–等指針相關(guān)操作予以重載的class template. 所有STL容器都附帶有自己專屬的迭代器,只有容器的設(shè)計(jì)者才知道如何遍歷自己的元素。原生指針(native pointer)也是一種迭代器。

    仿函數(shù):行為類似函數(shù),可作為算法的某種策略。從實(shí)現(xiàn)角度來看,仿函數(shù)是一種重載了operator()的class 或者class template

    適配器:一種用來修飾容器或者仿函數(shù)或迭代器接口的東西。

    空間配置器:負(fù)責(zé)空間的配置與管理。從實(shí)現(xiàn)角度看,配置器是一個(gè)實(shí)現(xiàn)了動態(tài)空間配置、空間管理、空間釋放的class tempalte.

    STL六大組件的交互關(guān)系,容器通過空間配置器取得數(shù)據(jù)存儲空間,算法通過迭代器存儲容器中的內(nèi)容,仿函數(shù)可以協(xié)助算法完成不同的策略的變化,適配器可以修飾仿函數(shù)。


    STL的優(yōu)點(diǎn)很明顯了:

    • STL 是 C++的一部分,因此不用額外安裝什么,它被內(nèi)建在你的編譯器之內(nèi)。
    • STL 的一個(gè)重要特性是將數(shù)據(jù)和操作分離。數(shù)據(jù)由容器類別加以管理,操作則由可定制的算法定義。迭代器在兩者之間充當(dāng)“粘合劑”,以使算法可以和容器交互運(yùn)作
    • 程序員可以不用思考 STL 具體的實(shí)現(xiàn)過程,只要能夠熟練使用 STL 就 OK 了。這樣他們就可以把精力放在程序開發(fā)的別的方面。
    • STL 具有高可重用性,高性能,高移植性,跨平臺的優(yōu)點(diǎn)。
    • 高可重用性:STL 中幾乎所有的代碼都采用了模板類和模版函數(shù)的方式實(shí)現(xiàn),這相比于傳統(tǒng)的由函數(shù)和類組成的庫來說提供了更好的代碼重用機(jī)會。
    • 高性能:如 map 可以高效地從十萬條記錄里面查找出指定的記錄,因?yàn)?map 是采用紅黑樹的變體實(shí)現(xiàn)的。
    • 高移植性:如在項(xiàng)目 A 上用 STL 編寫的模塊,可以直接移植到項(xiàng)目 B 上。

    ?

    三大組件介紹

    1. 容器

    幾乎可以說,任何特定的數(shù)據(jù)結(jié)構(gòu)都是為了實(shí)現(xiàn)某種特定的算法。STL容器就是將運(yùn)用最廣泛的一些數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)出來。
    常用的數(shù)據(jù)結(jié)構(gòu):數(shù)組(array) , 鏈表(list), tree(樹),棧(stack), 隊(duì)列(queue), 集合(set),映射表(map), 根據(jù)數(shù)據(jù)在容器中的排列特性,這些數(shù)據(jù)分為序列式容器和關(guān)聯(lián)式容器兩種。

    • 序列式容器強(qiáng)調(diào)值的排序,序列式容器中的每個(gè)元素均有固定的位置,除非用刪除或插入的操作改變這個(gè)位置。(Vector容器、Deque容器、List容器等。)
    • 關(guān)聯(lián)式容器是非線性的樹結(jié)構(gòu),更準(zhǔn)確的說是二叉樹結(jié)構(gòu)。各元素之間沒有嚴(yán)格的物理上的順序關(guān)系,也就是說元素在容器中并沒有保存元素置入容器時(shí)的邏輯順序。關(guān)聯(lián)式容器另一個(gè)顯著特點(diǎn)是:在值中選擇一個(gè)值作為關(guān)鍵字key,這個(gè)關(guān)鍵字對值起到索引的作用,方便查找。(Set/multiset容器 Map/multimap容器)

    2. 算法

    算法,問題的解法,以有限的步驟,解決邏輯或數(shù)學(xué)上的問題。

    我們所編寫的每個(gè)程序都是一個(gè)算法,其中的每個(gè)函數(shù)也都是一個(gè)算法,畢竟它們都是用來解決或大或小的邏輯問題或數(shù)學(xué)問題。STL收錄的算法經(jīng)過了數(shù)學(xué)上的效能分析與證明,是極具復(fù)用價(jià)值的,包括常用的排序,查找等等。特定的算法往往搭配特定的數(shù)據(jù)結(jié)構(gòu),算法與數(shù)據(jù)結(jié)構(gòu)相輔相成。

    算法分為:質(zhì)變算法和非質(zhì)變算法。

    • 質(zhì)變算法:是指運(yùn)算過程中會更改區(qū)間內(nèi)的元素的內(nèi)容。例如拷貝,替換,刪除等等
    • 非質(zhì)變算法:是指運(yùn)算過程中不會更改區(qū)間內(nèi)的元素內(nèi)容,例如查找、計(jì)數(shù)、遍歷、尋找極值等等

    3. 迭代器

    迭代器(iterator)是一種抽象的設(shè)計(jì)概念,現(xiàn)實(shí)程序語言中并沒有直接對應(yīng)于這個(gè)概念的實(shí)物。 在<<Design Patterns>>一書中提供了23種設(shè)計(jì)模式的完整描述, 其中iterator模式定義如下:提供一種方法,使之能夠依序?qū)ぴL某個(gè)容器所含的各個(gè)元素,而又無需暴露該容器的內(nèi)部表示方式。

    迭代器的設(shè)計(jì)思維-STL的關(guān)鍵所在,STL的中心思想在于將容器(container)和算法(algorithms)分開,彼此獨(dú)立設(shè)計(jì),最后再一貼膠著劑將他們撮合在一起。

    從技術(shù)角度來看,容器和算法的泛型化并不困難,c++的class template和function template可分別達(dá)到目標(biāo),如果設(shè)計(jì)出兩這個(gè)之間的良好的膠著劑,才是大難題。

    迭代器的種類:

    迭代器功能描述
    輸入迭代器提供對數(shù)據(jù)的只讀訪問只讀,支持++、==、!=
    輸出迭代器提供對數(shù)據(jù)的只寫訪問只寫,支持++
    前向迭代器?提供讀寫操作,并能向前推進(jìn)迭代器讀寫,支持++、==、!=
    雙向迭代器提供讀寫操作,并能向前和向后操作讀寫,支持++、–,
    隨機(jī)訪問迭代器提供讀寫操作,并能以跳躍的方式訪問容器的任意數(shù)據(jù),是功能最強(qiáng)的迭代器讀寫,支持++、–、[n]、-n、<、<=、>、>=

    演示:

    #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<vector> #include<algorithm> using namespace std;//STL 中的容器 算法 迭代器 void test01() {vector<int> v; //STL 中的標(biāo)準(zhǔn)容器之一 :動態(tài)數(shù)組v.push_back(1); //vector 容器提供的插入數(shù)據(jù)的方法v.push_back(5);v.push_back(3);v.push_back(7);//迭代器vector<int>::iterator pStart = v.begin(); //vector 容器提供了 begin()方法 返回指向第一個(gè)元素的迭代器vector<int>::iterator pEnd = v.end(); //vector 容器提供了 end()方法 返回指向最后一個(gè)元素下一個(gè)位置的迭代器//通過迭代器遍歷while (pStart != pEnd){cout << *pStart << " ";pStart++;}cout << endl;//算法 count 算法 用于統(tǒng)計(jì)元素的個(gè)數(shù)int n = count(pStart, pEnd, 5);cout << "n:" << n << endl; } //STL 容器不單單可以存儲基礎(chǔ)數(shù)據(jù)類型,也可以存儲類對象 class Teacher { public:Teacher(int age) :age(age){};~Teacher(){}; public:int age; }; void test02(){vector<Teacher> v; //存儲 Teacher 類型數(shù)據(jù)的容器Teacher t1(10), t2(20), t3(30);v.push_back(t1);v.push_back(t2);v.push_back(t3);vector<Teacher>::iterator pStart = v.begin();vector<Teacher>::iterator pEnd = v.end();//通過迭代器遍歷while (pStart != pEnd){cout << pStart->age << " ";pStart++;}cout << endl; } //存儲 Teacher 類型指針 void test03() {vector<Teacher*> v; //存儲 Teacher 類型指針Teacher* t1 = new Teacher(10);Teacher* t2 = new Teacher(20);Teacher* t3 = new Teacher(30);v.push_back(t1);v.push_back(t2);v.push_back(t3);//拿到容器迭代器vector<Teacher*>::iterator pStart = v.begin();vector<Teacher*>::iterator pEnd = v.end();//通過迭代器遍歷while (pStart != pEnd){cout << (*pStart)->age << " ";pStart++;}cout << endl; } //容器嵌套容器 難點(diǎn) void test04() {vector< vector<int> > v;vector<int>v1;vector<int>v2;vector<int>v3;for (int i = 0; i < 5;i++){v1.push_back(i);v2.push_back(i * 10);v3.push_back(i * 100);}v.push_back(v1);v.push_back(v2);v.push_back(v3);for (vector< vector<int> >::iterator it = v.begin(); it != v.end();it++){for (vector<int>::iterator subIt = (*it).begin(); subIt != (*it).end(); subIt ++){cout << *subIt << " ";}cout << endl;} }? int main() {//test01();//test02();//test03();test04();system("pause");return EXIT_SUCCESS; }


    常用容器

    1. string容器

    string容器基本概念

    C風(fēng)格字符串(以空字符結(jié)尾的字符數(shù)組)太過復(fù)雜難于掌握,不適合大程序的開發(fā),所以C++標(biāo)準(zhǔn)庫定義了一種string類,定義在頭文件<string>。
    String和c風(fēng)格字符串對比:

    • Char*是一個(gè)指針,String是一個(gè)類
    • string封裝了char*,管理這個(gè)字符串,是一個(gè)char*型的容器。
    • String封裝了很多實(shí)用的成員方法
    • 查找find,拷貝copy,刪除delete 替換replace,插入insert
    • 不用考慮內(nèi)存釋放和越界
    • string管理char*所分配的內(nèi)存。每一次string的復(fù)制,取值都由string類負(fù)責(zé)維護(hù),不用擔(dān)心復(fù)制越界和取值越界等。

    string容器常用操作

    string 構(gòu)造函數(shù)

    string();//創(chuàng)建一個(gè)空的字符串 例如: string str; ? ? ? string(const string& str);//使用一個(gè)string對象初始化另一個(gè)string對象 string(const char* s);//使用字符串s初始化 string(int n, char c);//使用n個(gè)字符c初始化?

    string基本賦值操作

    string& operator=(const char* s);//char*類型字符串 賦值給當(dāng)前的字符串 string& operator=(const string &s);//把字符串s賦給當(dāng)前的字符串 string& operator=(char c);//字符賦值給當(dāng)前的字符串 string& assign(const char *s);//把字符串s賦給當(dāng)前的字符串 string& assign(const char *s, int n);//把字符串s的前n個(gè)字符賦給當(dāng)前的字符串 string& assign(const string &s);//把字符串s賦給當(dāng)前字符串 string& assign(int n, char c);//用n個(gè)字符c賦給當(dāng)前字符串 string& assign(const string &s, int start, int n);//將s從start開始n個(gè)字符賦值給字符串

    string存取字符操作

    char& operator[](int n);//通過[]方式取字符 char& at(int n);//通過at方法獲取字符

    string拼接操作

    string& operator+=(const string& str);//重載+=操作符 string& operator+=(const char* str);//重載+=操作符 string& operator+=(const char c);//重載+=操作符 string& append(const char *s);//把字符串s連接到當(dāng)前字符串結(jié)尾 string& append(const char *s, int n);//把字符串s的前n個(gè)字符連接到當(dāng)前字符串結(jié)尾 string& append(const string &s);//同operator+=() string& append(const string &s, int pos, int n);//把字符串s中從pos開始的n個(gè)字符連接到當(dāng)前字符串結(jié)尾 string& append(int n, char c);//在當(dāng)前字符串結(jié)尾添加n個(gè)字符c

    string查找和替換

    int find(const string& str, int pos = 0) const; //查找str第一次出現(xiàn)位置,從pos開始查找 int find(const char* s, int pos = 0) const; ?//查找s第一次出現(xiàn)位置,從pos開始查找 int find(const char* s, int pos, int n) const; ?//從pos位置查找s的前n個(gè)字符第一次位置 int find(const char c, int pos = 0) const; ?//查找字符c第一次出現(xiàn)位置 int rfind(const string& str, int pos = npos) const;//查找str最后一次位置,從pos開始查找 int rfind(const char* s, int pos = npos) const;//查找s最后一次出現(xiàn)位置,從pos開始查找 int rfind(const char* s, int pos, int n) const;//從pos查找s的前n個(gè)字符最后一次位置 int rfind(const char c, int pos = 0) const; //查找字符c最后一次出現(xiàn)位置 string& replace(int pos, int n, const string& str); //替換從pos開始n個(gè)字符為字符串str string& replace(int pos, int n, const char* s); //替換從pos開始的n個(gè)字符為字符串s

    string比較操作

    /* compare函數(shù)在>時(shí)返回 1,<時(shí)返回 -1,==時(shí)返回 0。 比較區(qū)分大小寫,比較時(shí)參考字典順序,排越前面的越小。 大寫的A比小寫的a小。 */ int compare(const string &s) const;//與字符串s比較 int compare(const char *s) const;//與字符串s比較

    string子串

    string substr(int pos = 0, int n = npos) const;//返回由pos開始的n個(gè)字符組成的字符串

    string插入和刪除操作

    string& insert(int pos, const char* s); //插入字符串 string& insert(int pos, const string& str); //插入字符串 string& insert(int pos, int n, char c);//在指定位置插入n個(gè)字符c string& erase(int pos, int n = npos);//刪除從Pos開始的n個(gè)字符?

    string和c-style字符串轉(zhuǎn)換

    //string 轉(zhuǎn) char* string str = "it"; const char* cstr = str.c_str(); //char* 轉(zhuǎn) string? char* s = "it"; string str(s);
    在c++中存在一個(gè)從const char*到string的隱式類型轉(zhuǎn)換,卻不存在從一個(gè)string對象到C_string的自動類型轉(zhuǎn)換。對于string類型的字符串,可以通過c_str()函數(shù)返回string對象對應(yīng)的C_string.
    通常,程序員在整個(gè)程序中應(yīng)堅(jiān)持使用string類對象,直到必須將內(nèi)容轉(zhuǎn)化為char*時(shí)才將其轉(zhuǎn)換為C_string.

    為了修改string字符串的內(nèi)容,下標(biāo)操作符[]和at都會返回字符的引用。但當(dāng)字符串的內(nèi)存被重新分配之后,可能發(fā)生錯(cuò)誤.?

    string s = "abcdefg"; char& a = s[2]; char& b = s[3]; a = '1'; b = '2'; cout << s << endl; cout << (int*)s.c_str() << endl;s = "pppppppppppppppppppppppp";//a = '1'; //b = '2';cout << s << endl; cout << (int*)s.c_str() << endl;


    2. vector容器

    vector容器基本概念

    vector的數(shù)據(jù)安排以及操作方式,與array非常相似,兩者的唯一差別在于空間的運(yùn)用的靈活性。

    Array是靜態(tài)空間,一旦配置了就不能改變,要換大一點(diǎn)或者小一點(diǎn)的空間,可以,一切瑣碎得由自己來,首先配置一塊新的空間,然后將舊空間的數(shù)據(jù)搬往新空間,再釋放原來的空間。

    Vector是動態(tài)空間,隨著元素的加入,它的內(nèi)部機(jī)制會自動擴(kuò)充空間以容納新元素。因此vector的運(yùn)用對于內(nèi)存的合理利用與運(yùn)用的靈活性有很大的幫助,我們再也不必害怕空間不足而一開始就要求一個(gè)大塊頭的array了。

    Vector的實(shí)現(xiàn)技術(shù),關(guān)鍵在于其對大小的控制以及重新配置時(shí)的數(shù)據(jù)移動效率,一旦vector舊空間滿了,如果客戶每新增一個(gè)元素,vector內(nèi)部只是擴(kuò)充一個(gè)元素的空間,實(shí)為不智,因?yàn)樗^的擴(kuò)充空間(不論多大),一如剛所說,是”配置新空間-數(shù)據(jù)移動-釋放舊空間”的大工程,時(shí)間成本很高,應(yīng)該加入某種未雨綢繆的考慮,稍后我們便可以看到vector的空間配置策略。 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

    vector迭代器

    Vector維護(hù)一個(gè)線性空間,所以不論元素的型別如何,普通指針都可以作為vector的迭代器,因?yàn)関ector迭代器所需要的操作行為,如operaroe*, operator->, operator++, operator–, operator+, operator-, operator+=, operator-=, 普通指針天生具備。

    Vector支持隨機(jī)存取,而普通指針正有著這樣的能力。所以vector提供的是隨機(jī)訪問迭代器(Random Access Iterators).

    根據(jù)上述描述,如果我們寫如下的代碼:

    Vector<int>::iterator it1; Vector<Teacher>::iterator it2;

    it1的型別其實(shí)就是Int*,it2的型別其實(shí)就是Teacher*.

    #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<vector> using namespace std;int main(){vector<int> v;for (int i = 0; i < 10;i ++){v.push_back(i);cout << v.capacity() << endl; ?// v.capacity()容器的容量}system("pause");return EXIT_SUCCESS; }

    vector的數(shù)據(jù)結(jié)構(gòu)

    Vector所采用的數(shù)據(jù)結(jié)構(gòu)非常簡單,線性連續(xù)空間,它以兩個(gè)迭代器_Myfirst和_Mylast分別指向配置得來的連續(xù)空間中目前已被使用的范圍,并以迭代器_Myend指向整塊連續(xù)內(nèi)存空間的尾端。

    為了降低空間配置時(shí)的速度成本,vector實(shí)際配置的大小可能比客戶端需求大一些,以備將來可能的擴(kuò)充,這邊是容量的概念。換句話說,一個(gè)vector的容量永遠(yuǎn)大于或等于其大小,一旦容量等于大小,便是滿載,下次再有新增元素,整個(gè)vector容器就得另覓居所。

    所謂動態(tài)增加大小,并不是在原空間之后續(xù)接新空間(因?yàn)闊o法保證原空間之后尚有可配置的空間),而是一塊更大的內(nèi)存空間,然后將原數(shù)據(jù)拷貝新空間,并釋放原空間。因此,對vector的任何操作,一旦引起空間的重新配置,指向原vector的所有迭代器就都失效了。這是程序員容易犯的一個(gè)錯(cuò)誤,務(wù)必小心。

    vector常用API操作

    vector構(gòu)造函數(shù)

    vector<T> v; //采用模板實(shí)現(xiàn)類實(shí)現(xiàn),默認(rèn)構(gòu)造函數(shù) vector(v.begin(), v.end());//將v[begin(), end())區(qū)間中的元素拷貝給本身。 vector(n, elem);//構(gòu)造函數(shù)將n個(gè)elem拷貝給本身。 vector(const vector &vec);//拷貝構(gòu)造函數(shù)。 //例子 使用第二個(gè)構(gòu)造函數(shù) 我們可以... int arr[] = {2,3,4,1,9}; vector<int> v1(arr, arr + sizeof(arr) / sizeof(int));?

    vector常用賦值操作

    assign(beg, end);//將[beg, end)區(qū)間中的數(shù)據(jù)拷貝賦值給本身。 assign(n, elem);//將n個(gè)elem拷貝賦值給本身。 vector& operator=(const vector ?&vec);//重載等號操作符 swap(vec);// 將vec與本身的元素互換。

    vector大小操作

    size();//返回容器中元素的個(gè)數(shù) empty();//判斷容器是否為空 resize(int num);//重新指定容器的長度為num,若容器變長,則以默認(rèn)值填充新位置。如果容器變短,則末尾超出容器長度的元素被刪除。 resize(int num, elem);//重新指定容器的長度為num,若容器變長,則以elem值填充新位置。如果容器變短,則末尾超出容器長>度的元素被刪除。 capacity();//容器的容量 reserve(int len);//容器預(yù)留len個(gè)元素長度,預(yù)留位置不初始化,元素不可訪問。

    vector數(shù)據(jù)存取操作

    at(int idx); //返回索引idx所指的數(shù)據(jù),如果idx越界,拋出out_of_range異常。 operator[];//返回索引idx所指的數(shù)據(jù),越界時(shí),運(yùn)行直接報(bào)錯(cuò) front();//返回容器中第一個(gè)數(shù)據(jù)元素 back();//返回容器中最后一個(gè)數(shù)據(jù)元素

    vector插入和刪除操作

    insert(const_iterator pos, int count,ele);//迭代器指向位置pos插入count個(gè)元素ele. push_back(ele); //尾部插入元素ele pop_back();//刪除最后一個(gè)元素 erase(const_iterator start, const_iterator end);//刪除迭代器從start到end之間的元素 erase(const_iterator pos);//刪除迭代器指向的元素 clear();//刪除容器中所有元素

    vector 小demo: 巧用swap,收縮內(nèi)存空間

    #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<vector> using namespace std;int main(){vector<int> v;for (int i = 0; i < 100000;i ++){v.push_back(i);}cout << "capacity:" << v.capacity() << endl;cout << "size:" << v.size() << endl;//此時(shí) 通過resize改變?nèi)萜鞔笮.resize(10);cout << "capacity:" << v.capacity() << endl;cout << "size:" << v.size() << endl;//容量沒有改變vector<int>(v).swap(v);cout << "capacity:" << v.capacity() << endl;cout << "size:" << v.size() << endl;system("pause");return EXIT_SUCCESS; }

    reserve預(yù)留空間

    #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<vector> using namespace std;int main(){vector<int> v;//預(yù)先開辟空間v.reserve(100000);int* pStart = NULL;int count = 0;for (int i = 0; i < 100000;i ++){v.push_back(i);if (pStart != &v[0]){pStart = &v[0];count++;}}cout << "count:" << count << endl;system("pause");return EXIT_SUCCESS; }


    3. deque容器

    deque容器基本概念

    Vector容器是單向開口的連續(xù)內(nèi)存空間,deque則是一種雙向開口的連續(xù)線性空間。

    所謂的雙向開口,意思是可以在頭尾兩端分別做元素的插入和刪除操作,當(dāng)然,vector容器也可以在頭尾兩端插入元素,但是在其頭部操作效率奇差,無法被接受。

    ? ? ? ? ? ? ? ? ? ? ?

    Deque容器和vector容器最大的差異,一在于deque允許使用常數(shù)項(xiàng)時(shí)間對頭端進(jìn)行元素的插入和刪除操作。二在于deque沒有容量的概念,因?yàn)樗莿討B(tài)的以分段連續(xù)空間組合而成,隨時(shí)可以增加一段新的空間并鏈接起來,換句話說,像vector那樣,”舊空間不足而重新配置一塊更大空間,然后復(fù)制元素,再釋放舊空間”這樣的事情在deque身上是不會發(fā)生的。也因此,deque沒有必須要提供所謂的空間保留(reserve)功能.

    雖然deque容器也提供了Random Access Iterator,但是它的迭代器并不是普通的指針,其復(fù)雜度和vector不是一個(gè)量級,這當(dāng)然影響各個(gè)運(yùn)算的層面。因此,除非有必要,我們應(yīng)該盡可能的使用vector,而不是deque。對deque進(jìn)行的排序操作,為了最高效率,可將deque先完整的復(fù)制到一個(gè)vector中,對vector容器進(jìn)行排序,再復(fù)制回deque.

    deque容器實(shí)現(xiàn)原理

    Deque容器是連續(xù)的空間,至少邏輯上看來如此,連續(xù)現(xiàn)行空間總是令我們聯(lián)想到array和vector,array無法成長,vector雖可成長,卻只能向尾端成長,而且其成長其實(shí)是一個(gè)假象,事實(shí)上(1) 申請更大空間 (2)原數(shù)據(jù)復(fù)制新空間 (3)釋放原空間 三步驟,如果不是vector每次配置新的空間時(shí)都留有余裕,其成長假象所帶來的代價(jià)是非常昂貴的。

    Deque是由一段一段的定量的連續(xù)空間構(gòu)成。一旦有必要在deque前端或者尾端增加新的空間,便配置一段連續(xù)定量的空間,串接在deque的頭端或者尾端。Deque最大的工作就是維護(hù)這些分段連續(xù)的內(nèi)存空間的整體性的假象,并提供隨機(jī)存取的接口,避開了重新配置空間,復(fù)制,釋放的輪回,代價(jià)就是復(fù)雜的迭代器架構(gòu)。

    既然deque是分段連續(xù)內(nèi)存空間,那么就必須有中央控制,維持整體連續(xù)的假象,數(shù)據(jù)結(jié)構(gòu)的設(shè)計(jì)及迭代器的前進(jìn)后退操作頗為繁瑣。Deque代碼的實(shí)現(xiàn)遠(yuǎn)比vector或list都多得多。

    Deque采取一塊所謂的map(注意,不是STL的map容器)作為主控,這里所謂的map是一小塊連續(xù)的內(nèi)存空間,其中每一個(gè)元素(此處成為一個(gè)結(jié)點(diǎn))都是一個(gè)指針,指向另一段連續(xù)性內(nèi)存空間,稱作緩沖區(qū)。緩沖區(qū)才是deque的存儲空間的主體。

    ? ? ? ? ? ? ? ? ??

    deque常用API

    deque構(gòu)造函數(shù)

    deque<T> deqT;//默認(rèn)構(gòu)造形式 deque(beg, end);//構(gòu)造函數(shù)將[beg, end)區(qū)間中的元素拷貝給本身。 deque(n, elem);//構(gòu)造函數(shù)將n個(gè)elem拷貝給本身。 deque(const deque &deq);//拷貝構(gòu)造函數(shù)。

    deque賦值操作

    assign(beg, end);//將[beg, end)區(qū)間中的數(shù)據(jù)拷貝賦值給本身。 assign(n, elem);//將n個(gè)elem拷貝賦值給本身。 deque& operator=(const deque &deq); //重載等號操作符? swap(deq);// 將deq與本身的元素互換

    deque大小操作

    deque.size();//返回容器中元素的個(gè)數(shù) deque.empty();//判斷容器是否為空 deque.resize(num);//重新指定容器的長度為num,若容器變長,則以默認(rèn)值填充新位置。如果容器變短,則末尾超出容器長度的元素被刪除。 deque.resize(num, elem); //重新指定容器的長度為num,若容器變長,則以elem值填充新位置,如果容器變短,則末尾超出容器長度的元素被刪除。

    deque雙端插入和刪除操作

    push_back(elem);//在容器尾部添加一個(gè)數(shù)據(jù) push_front(elem);//在容器頭部插入一個(gè)數(shù)據(jù) pop_back();//刪除容器最后一個(gè)數(shù)據(jù) pop_front();//刪除容器第一個(gè)數(shù)據(jù)

    deque數(shù)據(jù)存取

    at(idx);//返回索引idx所指的數(shù)據(jù),如果idx越界,拋出out_of_range。 operator[];//返回索引idx所指的數(shù)據(jù),如果idx越界,不拋出異常,直接出錯(cuò)。 front();//返回第一個(gè)數(shù)據(jù)。 back();//返回最后一個(gè)數(shù)據(jù)

    deque插入操作

    insert(pos,elem);//在pos位置插入一個(gè)elem元素的拷貝,返回新數(shù)據(jù)的位置。 insert(pos,n,elem);//在pos位置插入n個(gè)elem數(shù)據(jù),無返回值。 insert(pos,beg,end);//在pos位置插入[beg,end)區(qū)間的數(shù)據(jù),無返回值。

    deque刪除操作

    clear();//移除容器的所有數(shù)據(jù) erase(beg,end);//刪除[beg,end)區(qū)間的數(shù)據(jù),返回下一個(gè)數(shù)據(jù)的位置。 erase(pos);//刪除pos位置的數(shù)據(jù),返回下一個(gè)數(shù)據(jù)的位置。

    4. stack容器

    stack容器基本概念

    stack是一種先進(jìn)后出(First In Last Out,FILO)的數(shù)據(jù)結(jié)構(gòu),它只有一個(gè)出口,形式如圖所示。stack容器允許新增元素,移除元素,取得棧頂元素,但是除了最頂端外,沒有任何其他方法可以存取stack的其他元素。換言之,stack不允許有遍歷行為。
    有元素推入棧的操作稱為:push,將元素推出stack的操作稱為pop.

    ? ? ? ? ? ? ? ? ? ? ? ? ?

    stack沒有迭代器

    Stack所有元素的進(jìn)出都必須符合”先進(jìn)后出”的條件,只有stack頂端的元素,才有機(jī)會被外界取用。Stack不提供遍歷功能,也不提供迭代器。

    stack常用API

    stack構(gòu)造函數(shù)

    stack<T> stkT;//stack采用模板類實(shí)現(xiàn), stack對象的默認(rèn)構(gòu)造形式:? stack(const stack &stk);//拷貝構(gòu)造函數(shù)

    stack賦值操作

    stack& operator=(const stack &stk);//重載等號操作符

    stack數(shù)據(jù)存取操作

    push(elem);//向棧頂添加元素 pop();//從棧頂移除第一個(gè)元素 top();//返回棧頂元素

    stack大小操作

    empty();//判斷堆棧是否為空 size();//返回堆棧的大小

    5. queue容器

    queue容器基本概念

    Queue是一種先進(jìn)先出(First In First Out,FIFO)的數(shù)據(jù)結(jié)構(gòu),它有兩個(gè)出口,queue容器允許從一端新增元素,從另一端移除元素。

    ? ? ? ? ? ? ? ? ??
    queue沒有迭代器

    Queue所有元素的進(jìn)出都必須符合”先進(jìn)先出”的條件,只有queue的頂端元素,才有機(jī)會被外界取用。Queue不提供遍歷功能,也不提供迭代器。

    queue常用API

    queue構(gòu)造函數(shù)

    queue<T> queT;//queue采用模板類實(shí)現(xiàn),queue對象的默認(rèn)構(gòu)造形式: queue(const queue &que);//拷貝構(gòu)造函數(shù)

    queue存取、插入和刪除操作

    push(elem);//往隊(duì)尾添加元素 pop();//從隊(duì)頭移除第一個(gè)元素 back();//返回最后一個(gè)元素 front();//返回第一個(gè)元素

    queue賦值操作

    queue& operator=(const queue &que);//重載等號操作符

    queue大小操作

    empty();//判斷隊(duì)列是否為空 size();//返回隊(duì)列的大小

    6. list容器

    list容器基本概念
    鏈表是一種物理存儲單元上非連續(xù)、非順序的存儲結(jié)構(gòu),數(shù)據(jù)元素的邏輯順序是通過鏈表中的指針鏈接次序?qū)崿F(xiàn)的。

    鏈表由一系列結(jié)點(diǎn)(鏈表中每一個(gè)元素稱為結(jié)點(diǎn))組成,結(jié)點(diǎn)可以在運(yùn)行時(shí)動態(tài)生成。每個(gè)結(jié)點(diǎn)包括兩個(gè)部分:一個(gè)是存儲數(shù)據(jù)元素的數(shù)據(jù)域,另一個(gè)是存儲下一個(gè)結(jié)點(diǎn)地址的指針域。

    相較于vector的連續(xù)線性空間,list就顯得負(fù)責(zé)許多,它的好處是每次插入或者刪除一個(gè)元素,就是配置或者釋放一個(gè)元素的空間。因此,list對于空間的運(yùn)用有絕對的精準(zhǔn),一點(diǎn)也不浪費(fèi)。而且,對于任何位置的元素插入或元素的移除,list永遠(yuǎn)是常數(shù)時(shí)間。

    List和vector是兩個(gè)最常被使用的容器。

    List容器是一個(gè)雙向鏈表。

    ? ? ? ?

    • 采用動態(tài)存儲分配,不會造成內(nèi)存浪費(fèi)和溢出
    • 鏈表執(zhí)行插入和刪除操作十分方便,修改指針即可,不需要移動大量元素
    • 鏈表靈活,但是空間和時(shí)間額外耗費(fèi)較大

    list容器的迭代器

    List容器不能像vector一樣以普通指針作為迭代器,因?yàn)槠涔?jié)點(diǎn)不能保證在同一塊連續(xù)的內(nèi)存空間上。

    List迭代器必須有能力指向list的節(jié)點(diǎn),并有能力進(jìn)行正確的遞增、遞減、取值、成員存取操作。所謂”list正確的遞增,遞減、取值、成員取用”是指,遞增時(shí)指向下一個(gè)節(jié)點(diǎn),遞減時(shí)指向上一個(gè)節(jié)點(diǎn),取值時(shí)取的是節(jié)點(diǎn)的數(shù)據(jù)值,成員取用時(shí)取的是節(jié)點(diǎn)的成員。

    由于list是一個(gè)雙向鏈表,迭代器必須能夠具備前移、后移的能力,所以list容器提供的是Bidirectional Iterators.

    List有一個(gè)重要的性質(zhì),插入操作和刪除操作都不會造成原有l(wèi)ist迭代器的失效。這在vector是不成立的,因?yàn)関ector的插入操作可能造成記憶體重新配置,導(dǎo)致原有的迭代器全部失效,甚至List元素的刪除,也只有被刪除的那個(gè)元素的迭代器失效,其他迭代器不受任何影響。

    list容器的數(shù)據(jù)結(jié)構(gòu)

    list容器不僅是一個(gè)雙向鏈表,而且還是一個(gè)循環(huán)的雙向鏈表。

    #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<list> using namespace std;int main(){list<int> myList;for (int i = 0; i < 10; i ++){myList.push_back(i);}list<int>::_Nodeptr node = ?myList._Myhead->_Next;for (int i = 0; i < myList._Mysize * 2;i++){cout << "Node:" << node->_Myval << endl;node = node->_Next;if (node == myList._Myhead){node = node->_Next;}}system("pause");return EXIT_SUCCESS; }

    list常用API

    list構(gòu)造函數(shù)

    list<T> lstT;//list采用采用模板類實(shí)現(xiàn),對象的默認(rèn)構(gòu)造形式: list(beg,end);//構(gòu)造函數(shù)將[beg, end)區(qū)間中的元素拷貝給本身。 list(n,elem);//構(gòu)造函數(shù)將n個(gè)elem拷貝給本身。 list(const list &lst);//拷貝構(gòu)造函數(shù)。

    list數(shù)據(jù)元素插入和刪除操作

    push_back(elem);//在容器尾部加入一個(gè)元素 pop_back();//刪除容器中最后一個(gè)元素 push_front(elem);//在容器開頭插入一個(gè)元素 pop_front();//從容器開頭移除第一個(gè)元素 insert(pos,elem);//在pos位置插e(cuò)lem元素的拷貝,返回新數(shù)據(jù)的位置。 insert(pos,n,elem);//在pos位置插入n個(gè)elem數(shù)據(jù),無返回值。 insert(pos,beg,end);//在pos位置插入[beg,end)區(qū)間的數(shù)據(jù),無返回值。 clear();//移除容器的所有數(shù)據(jù) erase(beg,end);//刪除[beg,end)區(qū)間的數(shù)據(jù),返回下一個(gè)數(shù)據(jù)的位置。 erase(pos);//刪除pos位置的數(shù)據(jù),返回下一個(gè)數(shù)據(jù)的位置。 remove(elem);//刪除容器中所有與elem值匹配的元素。

    list大小操作

    size();//返回容器中元素的個(gè)數(shù) empty();//判斷容器是否為空 resize(num);//重新指定容器的長度為num, 若容器變長,則以默認(rèn)值填充新位置。 如果容器變短,則末尾超出容器長度的元素被刪除。 resize(num, elem);//重新指定容器的長度為num, 若容器變長,則以elem值填充新位置。 如果容器變短,則末尾超出容器長度的元素被刪除。

    list賦值操作

    assign(beg, end);//將[beg, end)區(qū)間中的數(shù)據(jù)拷貝賦值給本身。 assign(n, elem);//將n個(gè)elem拷貝賦值給本身。 list& operator=(const list &lst);//重載等號操作符 swap(lst);//將lst與本身的元素互換。

    list數(shù)據(jù)的存取

    front();//返回第一個(gè)元素。 back();//返回最后一個(gè)元素。

    list反轉(zhuǎn)排序

    reverse();//反轉(zhuǎn)鏈表,比如lst包含1,3,5元素,運(yùn)行此方法后,lst就包含5,3,1元素。 sort(); //list排序

    7. set/multiset容器

    set容器基本概念

    Set的特性是。所有元素都會根據(jù)元素的鍵值自動被排序。Set的元素不像map那樣可以同時(shí)擁有實(shí)值和鍵值,set的元素即是鍵值又是實(shí)值。Set不允許兩個(gè)元素有相同的鍵值。

    我們不可以通過set的迭代器改變set元素的值,因?yàn)閟et元素值就是其鍵值,關(guān)系到set元素的排序規(guī)則。如果任意改變set元素值,會嚴(yán)重破壞set組織。換句話說,set的iterator是一種const_iterator.

    set擁有和list某些相同的性質(zhì),當(dāng)對容器中的元素進(jìn)行插入操作或者刪除操作的時(shí)候,操作之前所有的迭代器,在操作完成之后依然有效,被刪除的那個(gè)元素的迭代器必然是一個(gè)例外。

    multiset容器基本概念

    multiset特性及用法和set完全相同,唯一的差別在于它允許鍵值重復(fù)。set和multiset的底層實(shí)現(xiàn)是紅黑樹.

    set常用API

    set構(gòu)造函數(shù)

    set<T> st;//set默認(rèn)構(gòu)造函數(shù): mulitset<T> mst; //multiset默認(rèn)構(gòu)造函數(shù):? set(const set &st);//拷貝構(gòu)造函數(shù)

    set賦值操作

    set& operator=(const set &st);//重載等號操作符 swap(st);//交換兩個(gè)集合容器

    set大小操作

    size();//返回容器中元素的數(shù)目 empty();//判斷容器是否為空

    set插入和刪除操作

    insert(elem);//在容器中插入元素。 clear();//清除所有元素 erase(pos);//刪除pos迭代器所指的元素,返回下一個(gè)元素的迭代器。 erase(beg, end);//刪除區(qū)間[beg,end)的所有元素 ,返回下一個(gè)元素的迭代器。 erase(elem);//刪除容器中值為elem的元素。

    set查找操作

    find(key);//查找鍵key是否存在,若存在,返回該鍵的元素的迭代器;若不存在,返回set.end(); count(key);//查找鍵key的元素個(gè)數(shù) lower_bound(keyElem);//返回第一個(gè)key>=keyElem元素的迭代器。 upper_bound(keyElem);//返回第一個(gè)key>keyElem元素的迭代器。 equal_range(keyElem);//返回容器中key與keyElem相等的上下限的兩個(gè)迭代器。

    set的返回值 指定set排序規(guī)則舉例:

    //插入操作返回值 void test01(){set<int> s;pair<set<int>::iterator,bool> ret = s.insert(10);if (ret.second){cout << "插入成功:" << *ret.first << endl;}else{cout << "插入失敗:" << *ret.first << endl;}ret = s.insert(10);if(ret.second){cout << "插入成功:" << *ret.first << endl;}else{cout << "插入失敗:" << *ret.first << endl;}}struct MyCompare02{bool operator()(int v1,int v2){return v1 > v2;} };//set從大到小 void test02(){srand((unsigned int)time(NULL));//我們發(fā)現(xiàn)set容器的第二個(gè)模板參數(shù)可以設(shè)置排序規(guī)則,默認(rèn)規(guī)則是less<_Kty>set<int, MyCompare02> s;for (int i = 0; i < 10;i++){s.insert(rand() % 100);}for (set<int, MyCompare02>::iterator it = s.begin(); it != s.end(); it ++){cout << *it << " ";}cout << endl; }//set容器中存放對象 class Person{ public:Person(string name,int age){this->mName = name;this->mAge = age;} public:string mName;int mAge; };struct MyCompare03{bool operator()(const Person& p1,const Person& p2){return p1.mAge > p2.mAge;} };void test03(){set<Person, MyCompare03> s;Person p1("aaa", 20);Person p2("bbb", 30);Person p3("ccc", 40);Person p4("ddd", 50);s.insert(p1);s.insert(p2);s.insert(p3);s.insert(p4);for (set<Person, MyCompare03>::iterator it = s.begin(); it != s.end(); it++){cout << "Name:" << it->mName << " Age:" << it->mAge << endl;}}

    對組(pair)

    對組(pair)將一對值組合成一個(gè)值,這一對值可以具有不同的數(shù)據(jù)類型,兩個(gè)值可以分別用pair的兩個(gè)公有屬性first和second訪問。
    類模板:

    template <class T1, class T2> struct pair.

    創(chuàng)建對組:

    //第一種方法創(chuàng)建一個(gè)對組 pair<string, int> pair1(string("name"), 20); cout << pair1.first << endl; //訪問pair第一個(gè)值 cout << pair1.second << endl;//訪問pair第二個(gè)值 //第二種 pair<string, int> pair2 = make_pair("name", 30); cout << pair2.first << endl; cout << pair2.second << endl; //pair=賦值 pair<string, int> pair3 = pair2; cout << pair3.first << endl; cout << pair3.second << endl;

    8. map/multimap容器

    map/multimap基本概念

    Map的特性是,所有元素都會根據(jù)元素的鍵值自動排序。

    Map所有的元素都是pair,同時(shí)擁有實(shí)值和鍵值,pair的第一元素被視為鍵值,第二元素被視為實(shí)值,map不允許兩個(gè)元素有相同的鍵值。

    我們不可以通過map的迭代器改變map的鍵值, 因?yàn)閙ap的鍵值關(guān)系到map元素的排列規(guī)則,任意改變map鍵值將會嚴(yán)重破壞map組織。如果想要修改元素的實(shí)值,那么是可以的。

    Map和list擁有相同的某些性質(zhì),當(dāng)對它的容器元素進(jìn)行新增操作或者刪除操作時(shí),操作之前的所有迭代器,在操作完成之后依然有效,當(dāng)然被刪除的那個(gè)元素的迭代器必然是個(gè)例外。

    Multimap和map的操作類似,唯一區(qū)別multimap鍵值可重復(fù)。

    Map和multimap都是以紅黑樹為底層實(shí)現(xiàn)機(jī)制。

    map/multimap常用API

    map構(gòu)造函數(shù)

    map<T1, T2> mapTT;//map默認(rèn)構(gòu)造函數(shù):? map(const map &mp);//拷貝構(gòu)造函數(shù)

    map賦值操作

    map& operator=(const map &mp);//重載等號操作符 swap(mp);//交換兩個(gè)集合容器

    map大小操作

    size();//返回容器中元素的數(shù)目 empty();//判斷容器是否為空

    map插入數(shù)據(jù)元素操作

    map.insert(...); //往容器插入元素,返回pair<iterator,bool> map<int, string> mapStu; // 第一種 通過pair的方式插入對象 mapStu.insert(pair<int, string>(3, "小張")); // 第二種 通過pair的方式插入對象 mapStu.inset(make_pair(-1, "校長")); // 第三種 通過value_type的方式插入對象 mapStu.insert(map<int, string>::value_type(1, "小李")); // 第四種 通過數(shù)組的方式插入值 mapStu[3] = "小劉"; mapStu[5] = "小王";

    map刪除操作

    clear();//刪除所有元素 erase(pos);//刪除pos迭代器所指的元素,返回下一個(gè)元素的迭代器。 erase(beg,end);//刪除區(qū)間[beg,end)的所有元素 ,返回下一個(gè)元素的迭代器。 erase(keyElem);//刪除容器中key為keyElem的對組。

    map查找操作

    find(key);//查找鍵key是否存在,若存在,返回該鍵的元素的迭代器;/若不存在,返回map.end(); count(keyElem);//返回容器中key為keyElem的對組個(gè)數(shù)。對map來說,要么是0,要么是1。對multimap來說,值可能大于1。 lower_bound(keyElem);//返回第一個(gè)key>=keyElem元素的迭代器。 upper_bound(keyElem);//返回第一個(gè)key>keyElem元素的迭代器。 equal_range(keyElem);//返回容器中key與keyElem相等的上下限的兩個(gè)迭代器。

    multimap案例

    //公司今天招聘了5個(gè)員工,5名員工進(jìn)入公司之后,需要指派員工在那個(gè)部門工作 //人員信息有: 姓名 年齡 電話 工資等組成 //通過Multimap進(jìn)行信息的插入 保存 顯示 //分部門顯示員工信息 顯示全部員工信息#define _CRT_SECURE_NO_WARNINGS#include<iostream> #include<map> #include<string> #include<vector> using namespace std;//multimap 案例 //公司今天招聘了 5 個(gè)員工,5 名員工進(jìn)入公司之后,需要指派員工在那個(gè)部門工作 //人員信息有: 姓名 年齡 電話 工資等組成 //通過 Multimap 進(jìn)行信息的插入 保存 顯示 //分部門顯示員工信息 顯示全部員工信息#define SALE_DEPATMENT 1 //銷售部門 #define DEVELOP_DEPATMENT 2 //研發(fā)部門 #define FINACIAL_DEPATMENT 3 //財(cái)務(wù)部門 #define ALL_DEPATMENT 4 //所有部門//員工類 class person{ public:string name; //員工姓名int age; //員工年齡double salary; //員工工資string tele; //員工電話 };//創(chuàng)建5個(gè)員工 void CreatePerson(vector<person>& vlist){string seed = "ABCDE";for (int i = 0; i < 5; i++){person p;p.name = "員工";p.name += seed[i];p.age = rand() % 30 + 20;p.salary = rand() % 20000 + 10000;p.tele = "010-8888888";vlist.push_back(p);}}//5名員工分配到不同的部門 void PersonByGroup(vector<person>& vlist, multimap<int, person>& plist){int operate = -1; //用戶的操作for (vector<person>::iterator it = vlist.begin(); it != vlist.end(); it++){cout << "當(dāng)前員工信息:" << endl;cout << "姓名:" << it->name << " 年齡:" << it->age << " 工資:" << it->salary << " 電話:" << it->tele << endl;cout << "請對該員工進(jìn)行部門分配(1 銷售部門, 2 研發(fā)部門, 3 財(cái)務(wù)部門):" << endl;scanf("%d", &operate);while (true){if (operate == SALE_DEPATMENT){ ?//將該員工加入到銷售部門plist.insert(make_pair(SALE_DEPATMENT, *it));break;}else if (operate == DEVELOP_DEPATMENT){plist.insert(make_pair(DEVELOP_DEPATMENT, *it));break;}else if (operate == FINACIAL_DEPATMENT){plist.insert(make_pair(FINACIAL_DEPATMENT, *it));break;}else{cout << "您的輸入有誤,請重新輸入(1 銷售部門, 2 研發(fā)部門, 3 財(cái)務(wù)部門):" << endl;scanf("%d", &operate);}}}cout << "員工部門分配完畢!" << endl;cout << "***********************************************************" << endl;}//打印員工信息 void printList(multimap<int, person>& plist, int myoperate){if (myoperate == ALL_DEPATMENT){for (multimap<int, person>::iterator it = plist.begin(); it != plist.end(); it++){cout << "姓名:" << it->second.name << " 年齡:" << it->second.age << " 工資:" << it->second.salary << " 電話:" << it->second.tele << endl;}return;}multimap<int, person>::iterator it = plist.find(myoperate);int depatCount = plist.count(myoperate);int num = 0;if (it != plist.end()){while (it != plist.end() && num < depatCount){cout << "姓名:" << it->second.name << " 年齡:" << it->second.age << " 工資:" << it->second.salary << " 電話:" << it->second.tele << endl;it++;num++;}} }//根據(jù)用戶操作顯示不同部門的人員列表 void ShowPersonList(multimap<int, person>& plist, int myoperate){switch (myoperate){case SALE_DEPATMENT:printList(plist, SALE_DEPATMENT);break;case DEVELOP_DEPATMENT:printList(plist, DEVELOP_DEPATMENT);break;case FINACIAL_DEPATMENT:printList(plist, FINACIAL_DEPATMENT);break;case ALL_DEPATMENT:printList(plist, ALL_DEPATMENT);break;} }//用戶操作菜單 void PersonMenue(multimap<int, person>& plist){int flag = -1;int isexit = 0;while (true){cout << "請輸入您的操作((1 銷售部門, 2 研發(fā)部門, 3 財(cái)務(wù)部門, 4 所有部門, 0退出):" << endl;scanf("%d", &flag);switch (flag){case SALE_DEPATMENT:ShowPersonList(plist, SALE_DEPATMENT);break;case DEVELOP_DEPATMENT:ShowPersonList(plist, DEVELOP_DEPATMENT);break;case FINACIAL_DEPATMENT:ShowPersonList(plist, FINACIAL_DEPATMENT);break;case ALL_DEPATMENT:ShowPersonList(plist, ALL_DEPATMENT);break;case 0:isexit = 1;break;default:cout << "您的輸入有誤,請重新輸入!" << endl;break;}if (isexit == 1){break;}}}int main(){vector<person> ?vlist; //創(chuàng)建的5個(gè)員工 未分組multimap<int, person> plist; //保存分組后員工信息//創(chuàng)建5個(gè)員工CreatePerson(vlist);//5名員工分配到不同的部門PersonByGroup(vlist, plist);//根據(jù)用戶輸入顯示不同部門員工信息列表 或者 顯示全部員工的信息列表PersonMenue(plist);system("pause");return EXIT_SUCCESS; }

    STL容器使用時(shí)機(jī)

    .?vectordequelistsetmultisetmapmultimap
    典型內(nèi)存結(jié)構(gòu)單端數(shù)組雙端數(shù)組?雙向鏈表二叉樹二叉樹二叉樹二叉樹
    可隨機(jī)存取是?? ?是?? ?否?? ?否?? ?否?? ?對key而言:不是
    元素搜尋速度慢?? ?慢?? ?非常慢快?? ?快?? ?對key而言:快對key而言:快
    元素安插移除尾端頭尾兩端任何位置----


    vector的使用場景:比如軟件歷史操作記錄的存儲,我們經(jīng)常要查看歷史記錄,比如上一次的記錄,上上次的記錄,但卻不會去刪除記錄,因?yàn)橛涗浭鞘聦?shí)的描述。

    deque的使用場景:比如排隊(duì)購票系統(tǒng),對排隊(duì)者的存儲可以采用deque,支持頭端的快速移除,尾端的快速添加。如果采用vector,則頭端移除時(shí),會移動大量的數(shù)據(jù),速度慢。

    vector與deque的比較:
    一:vector.at()比deque.at()效率高,比如vector.at(0)是固定的,deque的開始位置?? ?卻是不固定的。
    二:如果有大量釋放操作的話,vector花的時(shí)間更少,這跟二者的內(nèi)部實(shí)現(xiàn)有關(guān)。
    三:deque支持頭部的快速插入與快速移除,這是deque的優(yōu)點(diǎn)。

    list的使用場景:比如公交車乘客的存儲,隨時(shí)可能有乘客下車,支持頻繁的不確實(shí)位置元素的移除插入。

    set的使用場景:比如對手機(jī)游戲的個(gè)人得分記錄的存儲,存儲要求從高分到低分的順序排列。

    map的使用場景:比如按ID號存儲十萬個(gè)用戶,想要快速要通過ID查找對應(yīng)的用戶。二叉樹的查找效率,這時(shí)就體現(xiàn)出來了。如果是vector容器,最壞的情況下可能要遍歷完整個(gè)容器才能找到該用戶。

    常用算法

    1. 函數(shù)對象

    重載函數(shù)調(diào)用操作符的類,其對象常稱為函數(shù)對象(function object),即它們是行為類似函數(shù)的對象,也叫仿函數(shù)(functor),其實(shí)就是重載“()”操作符,使得類對象可以像函數(shù)那樣調(diào)用。

    注意:

  • 函數(shù)對象(仿函數(shù))是一個(gè)類,不是一個(gè)函數(shù)。
  • 函數(shù)對象(仿函數(shù))重載了”() ”操作符使得它可以像函數(shù)一樣調(diào)用。
  • 分類:假定某個(gè)類有一個(gè)重載的operator(),而且重載的operator()要求獲取一個(gè)參數(shù),我們就將這個(gè)類稱為“一元仿函數(shù)”(unary functor);相反,如果重載的operator()要求獲取兩個(gè)參數(shù),就將這個(gè)類稱為“二元仿函數(shù)”(binary functor)。

    函數(shù)對象的作用:
    STL提供的算法往往都有兩個(gè)版本,其中一個(gè)版本表現(xiàn)出最常用的某種運(yùn)算,另一版本則允許用戶通過template參數(shù)的形式來指定所要采取的策略。

    //函數(shù)對象是重載了函數(shù)調(diào)用符號的類 class MyPrint { public:MyPrint(){m_Num = 0;}int m_Num;public:void operator() (int num){cout << num << endl;m_Num++;} }; //函數(shù)對象 //重載了()操作符的類實(shí)例化的對象,可以像普通函數(shù)那樣調(diào)用,可以有參數(shù) ,可以有返回值 void test01() {MyPrint myPrint;myPrint(20);} // 函數(shù)對象超出了普通函數(shù)的概念,可以保存函數(shù)的調(diào)用狀態(tài) void test02() {MyPrint myPrint;myPrint(20);myPrint(20);myPrint(20);cout << myPrint.m_Num << endl; }void doBusiness(MyPrint print,int num) {print(num); }//函數(shù)對象作為參數(shù) void test03() {//參數(shù)1:匿名函數(shù)對象doBusiness(MyPrint(),30); }

    總結(jié):

    1、函數(shù)對象通常不定義構(gòu)造函數(shù)和析構(gòu)函數(shù),所以在構(gòu)造和析構(gòu)時(shí)不會發(fā)生任何問題,避免了函數(shù)調(diào)用的運(yùn)行時(shí)問題。
    2、函數(shù)對象超出普通函數(shù)的概念,函數(shù)對象可以有自己的狀態(tài)
    3、函數(shù)對象可內(nèi)聯(lián)編譯,性能好。用函數(shù)指針幾乎不可能
    4、模版函數(shù)對象使函數(shù)對象具有通用性,這也是它的優(yōu)勢之一

    2. 謂詞

    謂詞是指普通函數(shù)或重載的operator()返回值是bool類型的函數(shù)對象(仿函數(shù))。如果operator接受一個(gè)參數(shù),那么叫做一元謂詞,如果接受兩個(gè)參數(shù),那么叫做二元謂詞,謂詞可作為一個(gè)判斷式。

    class GreaterThenFive { public:bool operator()(int num){return num > 5;}}; //一元謂詞 void test01() {vector<int> v;for (int i = 0; i < 10;i ++){v.push_back(i);}vector<int>::iterator it = ?find_if(v.begin(), v.end(), GreaterThenFive());if (it == v.end()){cout << "沒有找到" << endl;}else{cout << "找到了: " << *it << endl;} }//二元謂詞 class MyCompare { public:bool operator()(int num1, int num2){return num1 > num2;} };void test02() {vector<int> v;v.push_back(10);v.push_back(40);v.push_back(20);v.push_back(90);v.push_back(60);//默認(rèn)從小到大sort(v.begin(), v.end());for (vector<int>::iterator it = v.begin(); it != v.end();it++){cout << *it << " ";}cout << endl;cout << "----------------------------" << endl;//使用函數(shù)對象改變算法策略,排序從大到小sort(v.begin(), v.end(),MyCompare());for (vector<int>::iterator it = v.begin(); it != v.end(); it++){cout << *it << " ";}cout << endl; }

    3.內(nèi)建函數(shù)對象

    STL內(nèi)建了一些函數(shù)對象。分為:算數(shù)類函數(shù)對象,關(guān)系運(yùn)算類函數(shù)對象,邏輯運(yùn)算類仿函數(shù)。這些仿函數(shù)所產(chǎn)生的對象,用法和一般函數(shù)完全相同,當(dāng)然我們還可以產(chǎn)生無名的臨時(shí)對象來履行函數(shù)功能。使用內(nèi)建函數(shù)對象,需要引入頭文件

    #include<functional>

    6個(gè)算數(shù)類函數(shù)對象,除了negate是一元運(yùn)算,其他都是二元運(yùn)算。

    template<class T> T plus<T>//加法仿函數(shù) template<class T> T minus<T>//減法仿函數(shù) template<class T> T multiplies<T>//乘法仿函數(shù) template<class T> T divides<T>//除法仿函數(shù) template<class T> T modulus<T>//取模仿函數(shù) template<class T> T negate<T>//取反仿函數(shù)

    6個(gè)關(guān)系運(yùn)算類函數(shù)對象,每一種都是二元運(yùn)算。

    template<class T> bool equal_to<T>//等于 template<class T> bool not_equal_to<T>//不等于 template<class T> bool greater<T>//大于 template<class T> bool greater_equal<T>//大于等于 template<class T> bool less<T>//小于 template<class T> bool less_equal<T>//小于等于

    邏輯運(yùn)算類運(yùn)算函數(shù),not為一元運(yùn)算,其余為二元運(yùn)算。

    template<class T> bool logical_and<T>//邏輯與 template<class T> bool logical_or<T>//邏輯或 template<class T> bool logical_not<T>//邏輯非

    內(nèi)建函數(shù)對象舉例:

    //取反仿函數(shù) void test01() {negate<int> n;cout << n(50) << endl; }//加法仿函數(shù) void test02() {plus<int> p;cout << p(10, 20) << endl; }//大于仿函數(shù) void test03() {vector<int> v;srand((unsigned int)time(NULL));for (int i = 0; i < 10; i++){v.push_back(rand() % 100);}for (vector<int>::iterator it = v.begin(); it != v.end(); it++){cout << *it << " ";}cout << endl;sort(v.begin(), v.end(), greater<int>());for (vector<int>::iterator it = v.begin(); it != v.end(); it++){cout << *it << " ";}cout << endl;}

    4. 函數(shù)對象適配器

    //函數(shù)適配器bind1st bind2nd //現(xiàn)在我有這個(gè)需求 在遍歷容器的時(shí)候,我希望將容器中的值全部加上100之后顯示出來,怎么做? //我們直接給函數(shù)對象綁定參數(shù) 編譯階段就會報(bào)錯(cuò) //for_each(v.begin(), v.end(), bind2nd(myprint(),100)); //如果我們想使用綁定適配器,需要我們自己的函數(shù)對象繼承binary_function 或者 unary_function //根據(jù)我們函數(shù)對象是一元函數(shù)對象 還是二元函數(shù)對象 class MyPrint :public binary_function<int,int,void> { public:void operator()(int v1,int v2) const{cout << "v1 = : " << v1 << " v2 = :" <<v2 ?<< " v1+v2 = :" << (v1 + v2) << endl;?? ?} }; //1、函數(shù)適配器 void test01() {vector<int>v;for (int i = 0; i < 10; i++){v.push_back(i);}cout << "請輸入起始值:" << endl;int x;cin >> x;for_each(v.begin(), v.end(), bind1st(MyPrint(), x));//for_each(v.begin(), v.end(), bind2nd( MyPrint(),x )); } //總結(jié): ?bind1st和bind2nd區(qū)別? //bind1st : 將參數(shù)綁定為函數(shù)對象的第一個(gè)參數(shù) //bind2nd : 將參數(shù)綁定為函數(shù)對象的第二個(gè)參數(shù) //bind1st bind2nd將二元函數(shù)對象轉(zhuǎn)為一元函數(shù)對象class GreaterThenFive:public unary_function<int,bool> { public:bool operator ()(int v) const{return v > 5;} };//2、取反適配器 void test02() {vector <int> v;for (int i = 0; i < 10;i++){v.push_back(i);}// ?? ?vector<int>::iterator it = ?find_if(v.begin(), v.end(), GreaterThenFive()); //返回第一個(gè)大于5的迭代器 //?? ?vector<int>::iterator it = find_if(v.begin(), v.end(), ?not1(GreaterThenFive())); //返回第一個(gè)小于5迭代器//自定義輸入vector<int>::iterator it = find_if(v.begin(), v.end(), not1 ( bind2nd(greater<int>(),5)));if (it == v.end()){cout << "沒找到" << endl;}else{cout << "找到" << *it << endl;}//排序 ?二元函數(shù)對象sort(v.begin(), v.end(), not2(less<int>()));for_each(v.begin(), v.end(), [](int val){cout << val << " "; });} //not1 對一元函數(shù)對象取反 //not2 對二元函數(shù)對象取反void MyPrint03(int v,int v2) {cout << v + v2<< " "; }//3、函數(shù)指針適配器 ? ptr_fun void test03() {vector <int> v;for (int i = 0; i < 10; i++){v.push_back(i);}// ptr_fun( )把一個(gè)普通的函數(shù)指針適配成函數(shù)對象for_each(v.begin(), v.end(), bind2nd( ptr_fun( MyPrint03 ), 100)); }//4、成員函數(shù)適配器 class Person { public:Person(string name, int age){m_Name = name;m_Age = age;}//打印函數(shù)void ShowPerson(){cout << "成員函數(shù):" << "Name:" << m_Name << " Age:" << m_Age << endl;}void Plus100(){m_Age += 100;} public:string m_Name;int m_Age; };void MyPrint04(Person &p) {cout << "姓名:" << ?p.m_Name << " 年齡:" << p.m_Age << endl;};void test04() {vector <Person>v;Person p1("aaa", 10);Person p2("bbb", 20);Person p3("ccc", 30);Person p4("ddd", 40);v.push_back(p1);v.push_back(p2);v.push_back(p3);v.push_back(p4);//for_each(v.begin(), v.end(), MyPrint04);//利用 mem_fun_ref 將Person內(nèi)部成員函數(shù)適配for_each(v.begin(), v.end(), mem_fun_ref(&Person::ShowPerson)); // ?? ?for_each(v.begin(), v.end(), mem_fun_ref(&Person::Plus100)); // ?? ?for_each(v.begin(), v.end(), mem_fun_ref(&Person::ShowPerson)); }void test05(){vector<Person*> v1;//創(chuàng)建數(shù)據(jù)Person p1("aaa", 10);Person p2("bbb", 20);Person p3("ccc", 30);Person p4("ddd", 40);v1.push_back(&p1);v1.push_back(&p2);v1.push_back(&p3);v1.push_back(&p4);for_each(v1.begin(), v1.end(), mem_fun(&Person::ShowPerson)); }//如果容器存放的是對象指針, ?那么用mem_fun //如果容器中存放的是對象實(shí)體,那么用mem_fun_ref

    算法概述

    算法主要是由頭文件<algorithm><functional> <numeric>組成。
    <algorithm>是所有STL頭文件中最大的一個(gè),其中常用的功能涉及到比較,交換,查找,遍歷,復(fù)制,修改,反轉(zhuǎn),排序,合并等…
    <numeric>體積很小,只包括在幾個(gè)序列容器上進(jìn)行的簡單運(yùn)算的模板函數(shù).
    <functional> 定義了一些模板類,用以聲明函數(shù)對象。

    1. 常用遍歷算法

    /*遍歷算法 遍歷容器元素@param beg 開始迭代器@param end 結(jié)束迭代器@param _callback ?函數(shù)回調(diào)或者函數(shù)對象@return 函數(shù)對象 */ for_each(iterator beg, iterator end, _callback); /*transform算法 將指定容器區(qū)間元素搬運(yùn)到另一容器中注意 : transform 不會給目標(biāo)容器分配內(nèi)存,所以需要我們提前分配好內(nèi)存@param beg1 源容器開始迭代器@param end1 源容器結(jié)束迭代器@param beg2 目標(biāo)容器開始迭代器@param _cakkback 回調(diào)函數(shù)或者函數(shù)對象@return 返回目標(biāo)容器迭代器 */ transform(iterator beg1, iterator end1, iterator beg2, _callbakc)for_each: /*template<class _InIt,class _Fn1> inline void for_each(_InIt _First, _InIt _Last, _Fn1 _Func) {for (; _First != _Last; ++_First)_Func(*_First); }*///普通函數(shù) void print01(int val){cout << val << " "; } //函數(shù)對象 struct print001{void operator()(int val){cout << val << " ";} };//for_each算法基本用法 void test01(){vector<int> v;for (int i = 0; i < 10;i++){v.push_back(i);}//遍歷算法for_each(v.begin(), v.end(), print01);cout << endl;for_each(v.begin(), v.end(), print001());cout << endl;}struct print02{print02(){mCount = 0;}void operator()(int val){cout << val << " ";mCount++;}int mCount; };//for_each返回值 void test02(){vector<int> v;for (int i = 0; i < 10; i++){v.push_back(i);}print02 p = for_each(v.begin(), v.end(), print02());cout << endl;cout << p.mCount << endl; }struct print03 : public binary_function<int, int, void>{void operator()(int val,int bindParam) const{cout << val + bindParam << " ";} };//for_each綁定參數(shù)輸出 void test03(){vector<int> v;for (int i = 0; i < 10; i++){v.push_back(i);}for_each(v.begin(), v.end(), bind2nd(print03(),100)); }transform: //transform 將一個(gè)容器中的值搬運(yùn)到另一個(gè)容器中 /*template<class _InIt, class _OutIt, class _Fn1> inline?_OutIt _Transform(_InIt _First, _InIt _Last,_OutIt _Dest, _Fn1 _Func){?? ?for (; _First != _Last; ++_First, ++_Dest)*_Dest = _Func(*_First);return (_Dest);}template<class _InIt1,class _InIt2,class _OutIt,class _Fn2> inline_OutIt _Transform(_InIt1 _First1, _InIt1 _Last1,_InIt2 _First2, _OutIt _Dest, _Fn2 _Func){?? ?for (; _First1 != _Last1; ++_First1, ++_First2, ++_Dest)*_Dest = _Func(*_First1, *_First2);return (_Dest);} */struct transformTest01{int operator()(int val){return val + 100;} }; struct print01{void operator()(int val){cout << val << " ";} }; void test01(){vector<int> vSource;for (int i = 0; i < 10;i ++){vSource.push_back(i + 1);}//目標(biāo)容器vector<int> vTarget;//給vTarget開辟空間vTarget.resize(vSource.size());//將vSource中的元素搬運(yùn)到vTargetvector<int>::iterator it = transform(vSource.begin(), vSource.end(), vTarget.begin(), transformTest01());//打印for_each(vTarget.begin(), vTarget.end(), print01()); cout << endl;}//將容器1和容器2中的元素相加放入到第三個(gè)容器中 struct transformTest02{int operator()(int v1,int v2){return v1 + v2;} }; void test02(){vector<int> vSource1;vector<int> vSource2;for (int i = 0; i < 10; i++){vSource1.push_back(i + 1);?? ?}//目標(biāo)容器vector<int> vTarget;//給vTarget開辟空間vTarget.resize(vSource1.size());transform(vSource1.begin(), vSource1.end(), vSource2.begin(),vTarget.begin(), transformTest02());//打印for_each(vTarget.begin(), vTarget.end(), print01()); cout << endl; }

    2. 常用查找算法

    /*find算法 查找元素@param beg 容器開始迭代器@param end 容器結(jié)束迭代器@param value 查找的元素@return 返回查找元素的位置 */ find(iterator beg, iterator end, value) /*find_if算法 條件查找@param beg 容器開始迭代器@param end 容器結(jié)束迭代器@param ?callback 回調(diào)函數(shù)或者謂詞(返回bool類型的函數(shù)對象)@return bool 查找返回true 否則false */ find_if(iterator beg, iterator end, _callback);/*adjacent_find算法 查找相鄰重復(fù)元素@param beg 容器開始迭代器@param end 容器結(jié)束迭代器@param ?_callback 回調(diào)函數(shù)或者謂詞(返回bool類型的函數(shù)對象)@return 返回相鄰元素的第一個(gè)位置的迭代器 */ adjacent_find(iterator beg, iterator end, _callback); /*binary_search算法 二分查找法注意: 在無序序列中不可用@param beg 容器開始迭代器@param end 容器結(jié)束迭代器@param value 查找的元素@return bool 查找返回true 否則false */ bool binary_search(iterator beg, iterator end, value); /*count算法 統(tǒng)計(jì)元素出現(xiàn)次數(shù)@param beg 容器開始迭代器@param end 容器結(jié)束迭代器@param ?value回調(diào)函數(shù)或者謂詞(返回bool類型的函數(shù)對象)@return int返回元素個(gè)數(shù) */ count(iterator beg, iterator end, value); /*count算法 統(tǒng)計(jì)元素出現(xiàn)次數(shù)@param beg 容器開始迭代器@param end 容器結(jié)束迭代器@param ?callback 回調(diào)函數(shù)或者謂詞(返回bool類型的函數(shù)對象)@return int返回元素個(gè)數(shù) */ count_if(iterator beg, iterator end, _callback);

    3. 常用排序算法

    /*merge算法 容器元素合并,并存儲到另一容器中@param beg1 容器1開始迭代器@param end1 容器1結(jié)束迭代器@param beg2 容器2開始迭代器@param end2 容器2結(jié)束迭代器@param dest ?目標(biāo)容器開始迭代器 */ merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest) /*sort算法 容器元素排序注意:兩個(gè)容器必須是有序的@param beg 容器1開始迭代器@param end 容器1結(jié)束迭代器@param _callback 回調(diào)函數(shù)或者謂詞(返回bool類型的函數(shù)對象) */ sort(iterator beg, iterator end, _callback) /*sort算法 對指定范圍內(nèi)的元素隨機(jī)調(diào)整次序@param beg 容器開始迭代器@param end 容器結(jié)束迭代器 */ random_shuffle(iterator beg, iterator end) /*reverse算法 反轉(zhuǎn)指定范圍的元素@param beg 容器開始迭代器@param end 容器結(jié)束迭代器 */ reverse(iterator beg, iterator end)

    4. 常用拷貝和替換算法

    /*copy算法 將容器內(nèi)指定范圍的元素拷貝到另一容器中@param beg 容器開始迭代器@param end 容器結(jié)束迭代器@param dest 目標(biāo)起始迭代器 */ copy(iterator beg, iterator end, iterator dest) /*replace算法 將容器內(nèi)指定范圍的舊元素修改為新元素@param beg 容器開始迭代器@param end 容器結(jié)束迭代器@param oldvalue 舊元素@param oldvalue 新元素 */ replace(iterator beg, iterator end, oldvalue, newvalue) /*replace_if算法 將容器內(nèi)指定范圍滿足條件的元素替換為新元素@param beg 容器開始迭代器@param end 容器結(jié)束迭代器@param callback函數(shù)回調(diào)或者謂詞(返回Bool類型的函數(shù)對象)@param oldvalue 新元素 */ replace_if(iterator beg, iterator end, _callback, newvalue) /*swap算法 互換兩個(gè)容器的元素@param c1容器1@param c2容器2 */ swap(container c1, container c2)

    5. 常用算數(shù)生成算法

    /*accumulate算法 計(jì)算容器元素累計(jì)總和@param beg 容器開始迭代器@param end 容器結(jié)束迭代器@param value累加值 */ accumulate(iterator beg, iterator end, value) /*fill算法 向容器中添加元素@param beg 容器開始迭代器@param end 容器結(jié)束迭代器@param value t填充元素 */ fill(iterator beg, iterator end, value)

    6. 常用集合算法

    /*set_intersection算法 求兩個(gè)set集合的交集注意:兩個(gè)集合必須是有序序列@param beg1 容器1開始迭代器@param end1 容器1結(jié)束迭代器@param beg2 容器2開始迭代器@param end2 容器2結(jié)束迭代器@param dest ?目標(biāo)容器開始迭代器@return 目標(biāo)容器的最后一個(gè)元素的迭代器地址 */ set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest) /*set_union算法 求兩個(gè)set集合的并集注意:兩個(gè)集合必須是有序序列@param beg1 容器1開始迭代器@param end1 容器1結(jié)束迭代器@param beg2 容器2開始迭代器@param end2 容器2結(jié)束迭代器@param dest ?目標(biāo)容器開始迭代器@return 目標(biāo)容器的最后一個(gè)元素的迭代器地址 */ set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest) /*set_difference算法 求兩個(gè)set集合的差集注意:兩個(gè)集合必須是有序序列@param beg1 容器1開始迭代器@param end1 容器1結(jié)束迭代器@param beg2 容器2開始迭代器@param end2 容器2結(jié)束迭代器@param dest ?目標(biāo)容器開始迭代器@return 目標(biāo)容器的最后一個(gè)元素的迭代器地址 */ set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)

    ?

    總結(jié)

    以上是生活随笔為你收集整理的【C/C++学习】之STL详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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

    天天操天天添天天吹 | 久草在线99| 亚洲一区网 | 在线视频一二区 | 97色狠狠 | 521色香蕉网站在线观看 | 成人久久| 免费在线观看av网址 | 五月婷婷视频在线观看 | 911久久香蕉国产线看观看 | 中文字幕电影高清在线观看 | 久久97超碰 | 精品国产伦一区二区三区观看说明 | 日韩xxxx视频 | 日本在线视频一区二区三区 | 亚洲精品视频偷拍 | 精品久久久久国产免费第一页 | 综合久久精品 | 国产精品久久久久久久妇 | 丁香视频在线观看 | 日韩av成人免费看 | 亚洲毛片在线观看. | 不卡视频在线看 | 免费看国产曰批40分钟 | 97涩涩视频| 国产在线日本 | 午夜精品久久久久久久99 | 国产成人免费在线 | 在线视频观看成人 | 国产精品国产三级在线专区 | 婷婷精品国产欧美精品亚洲人人爽 | 欧美高清视频不卡网 | 国产精品美女久久久久久久久久久 | 999久久久久久久久 69av视频在线观看 | 97超视频 | 色99网| 欧美一区免费观看 | 久草a在线 | 成人黄色影片在线 | 嫩模bbw搡bbbb搡bbbb | 99精品网站 | 久久精品一区二区三区视频 | 黄色影院在线免费观看 | 国产高清永久免费 | www国产在线| 热久久视久久精品18亚洲精品 | 操久在线 | 久久久久久不卡 | 亚洲激情综合 | 六月丁香在线视频 | 日韩精品视频免费专区在线播放 | 欧美性猛片,| 日本一区二区不卡高清 | 国产91在线观看 | 欧美激情精品久久久久 | 中文字幕国产精品 | 亚洲视频在线播放 | av在线电影网站 | av在线网站免费观看 | 最近中文字幕大全中文字幕免费 | 一区免费视频 | 97av视频在线观看 | 中文字幕无吗 | 国产精品欧美久久久久久 | 久久久国产精品网站 | 久久视频国产 | 日本一区二区三区免费看 | 久久96国产精品久久99漫画 | 手机看片福利 | 91大片网站| 亚洲最新在线 | 精品在线你懂的 | 亚洲精品一区二区18漫画 | 精品国产乱码久久久久久三级人 | www激情网| 丁香婷婷色综合亚洲电影 | 日日干 天天干 | 国产福利在线免费观看 | 999久久国产精品免费观看网站 | 国产精品videoxxxx | 麻豆传媒视频在线免费观看 | 免费观看一区二区三区视频 | 日韩中文久久 | 国产精品美女久久久网av | 久久色视频 | 久久久福利视频 | 成人av免费在线播放 | 欧美激情视频免费看 | 国产精品18毛片一区二区 | 8x成人免费视频 | 日本精品视频一区 | 99视频99| 日韩欧美在线一区 | 欧美精品在线一区二区 | 91精品国产福利 | 婷婷在线不卡 | 国内精品在线观看视频 | 96av视频| 干干操操 | 国产美女无遮挡永久免费 | 中文字幕在线色 | 久久久www成人免费精品 | 韩国一区二区三区视频 | 99久久综合国产精品二区 | 久久手机看片 | 亚洲精品玖玖玖av在线看 | 九九九热精品免费视频观看网站 | 日日夜夜免费精品视频 | 91麻豆精品国产91久久久久久 | 亚洲最新av在线网站 | 久久艹影院 | 在线中文字幕播放 | 夜夜骑日日| av片中文 | 国产成人久久av977小说 | 日韩久久久| 国产精品综合久久久久 | 日韩大片在线免费观看 | 欧美一级艳片视频免费观看 | 久久 精品一区 | 一区二区三区在线免费观看视频 | 热久久精品在线 | 免费a v网站 | 黄色大全在线观看 | 96精品在线| 亚洲女同videos| 日韩特黄一级欧美毛片特黄 | 日日干,天天干 | 成人福利在线观看 | www.五月婷婷.com | 精品毛片久久久久久 | 国产一区在线不卡 | 天天在线视频色 | 免费视频资源 | 亚洲欧洲美洲av | 黄色片网站 | 亚洲精品在线观看不卡 | 99精品国产免费久久 | 国产一区二区在线播放视频 | 免费a一级 | 九九九九色| 国产精品乱码久久久久久1区2区 | 91av社区 | 日韩精品专区 | 日韩精品一区二区三区免费视频观看 | 五月婷婷深开心 | 天堂av高清 | 91精品秘密在线观看 | 亚洲aⅴ在线 | 美女中文字幕 | 99精品国产福利在线观看免费 | 国产91精品看黄网站在线观看动漫 | 天堂麻豆| 午夜视频在线观看一区二区三区 | 99视频精品免费观看, | 国产一区二区久久精品 | 成人av在线影视 | 99久久99| 国产成人av一区二区三区在线观看 | 亚洲综合色播 | 欧美一级片在线免费观看 | 视频国产| 国产午夜三级一区二区三桃花影视 | 极品中文字幕 | 婷婷丁香六月天 | 99精品国产福利在线观看免费 | 婷婷六月中文字幕 | 91在线入口 | 国产黄影院色大全免费 | 欧美激情视频在线观看免费 | 日本精品视频在线观看 | 免费合欢视频成人app | 国产麻豆剧传媒免费观看 | 天天摸天天弄 | 久久综合国产伦精品免费 | 天天色中文 | 国产精品女 | 又黄又爽的免费高潮视频 | 中文字幕免费观看 | 黄色在线观看免费网站 | 亚洲欧美国产日韩在线观看 | 日韩专区在线观看 | 国内精品久久久久影院男同志 | 中文字幕一区二区三区乱码不卡 | 在线免费黄 | 在线观看久久 | 亚洲精品国精品久久99热 | 日韩精品一区二区不卡 | 毛片随便看 | 夜添久久精品亚洲国产精品 | 啪啪肉肉污av国网站 | 精品一二三四五区 | 午夜免费福利视频 | 国产精品大全 | 免费国产黄线在线观看视频 | 久久电影中文字幕视频 | 成年人在线观看视频免费 | 中文永久字幕 | 免费欧美高清视频 | 狠狠操夜夜操 | 伊人天天干 | 视频1区2区 | 欧美一级在线观看视频 | av黄色av| 欧美一区二区在线 | 精品国产亚洲在线 | 日韩爱爱网站 | 国产精品亚洲综合久久 | 福利视频 | 国产精品不卡一区 | 97超碰在线免费观看 | 天天爽天天做 | 天天色天天操综合 | 日韩精品免费一区二区在线观看 | 日本三级在线观看中文字 | 中文国产在线观看 | 伊人五月天婷婷 | 日韩免费在线视频观看 | 欧美久久九九 | 成人国产精品久久久久久亚洲 | 超碰人人国产 | 91九色最新地址 | 波多野结衣电影久久 | 日韩一级电影在线观看 | 免费观看一级成人毛片 | 九九热视频在线播放 | 国产小视频福利在线 | 日本精品久久久久中文字幕 | 免费在线观看a v | 亚洲专区在线视频 | 国产成人精品一区一区一区 | av高清一区 | av线上看 | 久久五月情影视 | 亚洲jizzjizz日本少妇 | 精品亚洲在线 | 久草久草在线 | 一区二区三区在线看 | 99精品在线免费观看 | 亚洲www天堂com | 夜又临在线观看 | 在线观看黄色的网站 | 九九久久在线看 | 久精品在线观看 | 成人国产精品一区 | 久草综合视频 | 天天射天天爱天天干 | 久久免费99精品久久久久久 | 日韩影视大全 | 狠狠色综合欧美激情 | 欧美成年人在线观看 | 免费观看性生交 | 综合色站| 蜜臀久久99静品久久久久久 | 夜夜操网| 国产黄色片网站 | 亚洲一区二区黄色 | 欧洲色综合 | 911在线 | 亚洲精品乱码久久久久久久久久 | 一色屋精品视频在线观看 | 久久精品毛片基地 | 干 操 插 | 在线成人免费电影 | 99久久999久久久精玫瑰 | 五月婷婷丁香 | 国产成人精品久久二区二区 | 婷婷免费视频 | 激情婷婷| 91视频在线自拍 | 亚洲精品国产精品乱码在线观看 | 丁香激情综合久久伊人久久 | 精品影院 | 亚洲一区二区天堂 | 精品视频久久 | 久久精品2 | 久草国产视频 | 国产精品一区二区久久久 | 日韩精品在线播放 | 成年人免费电影 | 片网站 | 日韩成人在线一区二区 | 91精品在线播放 | 亚洲精品在线网站 | 九九热精品国产 | 深爱激情亚洲 | 99热.com| 国内精品美女在线观看 | 韩日成人av | 久久影视精品 | 亚洲欧美va | 久草在线视频网 | 黄色网址av | 久久伊人综合 | 久草在线视频在线 | 69欧美视频 | 国产黄在线播放 | av性网站| 国产专区精品 | 99热网站| 成人在线视频你懂的 | 国产在线一区二区三区播放 | 免费三级a | 中文字幕久久精品亚洲乱码 | 国产区精品在线 | 日韩视频一区二区三区在线播放免费观看 | www狠狠操| 国产精品久久一卡二卡 | 欧美一区成人 | 91九色国产蝌蚪 | 国产一区免费观看 | 99久久精品久久久久久动态片 | 人成午夜视频 | 亚洲永久国产精品 | 国产婷婷精品 | 亚洲在线成人精品 | 中文字幕影视 | 久久综合五月天婷婷伊人 | 在线v片免费观看视频 | 国产日本在线 | 99视频精品视频高清免费 | 国产精品 欧美 日韩 | 天堂av网址| 黄色在线看网站 | 久久 地址 | 色噜噜在线观看 | 成人久久18免费网站图片 | 最新99热| 免费观看成人av | 黄色亚洲大片免费在线观看 | av在线免费播放 | 超碰国产在线观看 | 五月天中文在线 | a在线免费观看视频 | 国产精品第7页 | 最新免费av在线 | 韩国av一区二区 | 婷婷色av | 日韩久久精品一区二区 | 国产高清免费 | 欧美一级片免费播放 | 午夜久久美女 | 激情视频免费观看 | 亚洲理论片在线观看 | 免费看污污视频的网站 | 亚洲成人精品在线观看 | 亚洲欧美视频在线 | 在线日韩精品视频 | 国产麻豆精品久久一二三 | 黄色在线免费观看网址 | 免费婷婷 | 日韩欧美区 | 久久深夜福利免费观看 | 日韩免费视频播放 | 国产网红在线观看 | 6699私人影院 | 成人黄色小说在线观看 | 九色精品| 国产精品久久久久久久久搜平片 | 国内精品视频在线 | 久久亚洲影院 | 国产色在线,com | 欧洲精品久久久久毛片完整版 | 久久狠狠干 | 国产精品福利午夜在线观看 | 久久99亚洲精品 | 69成人在线| 麻豆视频在线免费看 | 免费观看午夜视频 | 国产黄色片免费看 | 日韩在线不卡av | 特级a毛片 | 黄色在线小网站 | 欧美一区日韩一区 | 国产精品一区二区中文字幕 | 国产麻豆精品免费视频 | 色婷婷综合久久久久中文字幕1 | 精品国产乱码久久久久久1区2匹 | 狠狠色综合网站久久久久久久 | 久久免费视频一区 | 亚洲欧美视频一区二区三区 | 五月天天av | 少妇资源站 | 免费看的黄色 | 91看片网址 | 国产精品原创 | 人人爽人人爱 | 粉嫩aⅴ一区二区三区 | 中文成人字幕 | av千婊在线免费观看 | 日韩视频区 | 日韩成人高清在线 | 午夜精品久久久久久久99热影院 | www.日日日.com| 日韩亚洲在线 | 黄色网在线免费观看 | 日韩欧美在线免费观看 | 免费看的黄色录像 | 国产一区二区三区视频在线 | 一本一道久久a久久综合蜜桃 | 国产精品中文字幕在线播放 | 久久精品国亚洲 | 国产不卡一二三区 | 亚洲理论在线观看电影 | 999久久a精品合区久久久 | 亚洲另类xxxx | 成人av网站在线 | 亚洲美女视频在线观看 | 久久五月婷婷丁香 | 午夜精品久久久久久久久久久 | 日本黄色大片儿 | 日韩免费视频播放 | 91在线看视频免费 | av在线播放中文字幕 | 久久夜靖品 | 久久夜av| 国产精品成人一区二区 | 九九电影在线 | 黄色免费观看视频 | 国产亚洲一级高清 | 亚洲区精品视频 | 五月天久久激情 | 国产精品嫩草55av | 女人18毛片90分钟 | 91资源在线视频 | 国产一区二区在线免费 | 黄色精品久久 | 色婷婷九月 | 国产一区二区精品久久 | 日日夜夜狠狠操 | 97视频网址 | 国产精品视频区 | 亚洲欧美在线观看视频 | 狠狠躁天天躁综合网 | 久久久网址 | 99色国产 | 国产 一区二区三区 在线 | 美女视频网 | 国产中文视频 | 日日麻批40分钟视频免费观看 | 免费人成在线观看 | 免费情趣视频 | 日韩欧美视频一区 | 日韩欧美精品在线 | 黄色片网站av | 亚洲精品小区久久久久久 | 亚洲成年人免费网站 | 中日韩三级视频 | 国内成人精品2018免费看 | 久久久久亚洲精品国产 | 99爱精品视频 | 四虎小视频 | 久久99精品热在线观看 | 在线观看黄色免费视频 | 欧美夫妻生活视频 | av高清一区二区三区 | 国产精品久久久毛片 | 免费成人在线视频网站 | 日本久久久久久久久久 | 丁香花在线观看免费完整版视频 | 在线亚洲播放 | 国产精品观看在线亚洲人成网 | 亚洲精品在 | 六月丁香激情综合色啪小说 | 97热视频| 国产成人精品午夜在线播放 | 国产精品成人自产拍在线观看 | 欧美极度另类性三渗透 | 91亚洲精品乱码久久久久久蜜桃 | 又色又爽的网站 | 亚洲aⅴ久久精品 | 国产专区精品 | 91高清视频在线 | 国产视频在线观看免费 | 99久久精品国 | 香蕉色综合 | 在线观看免费日韩 | 成人欧美一区二区三区黑人麻豆 | 亚洲综合爱 | 色综合久久88色综合天天免费 | 操操操操网 | 在线直播av | 中文在线a√在线 | 亚洲日本在线视频观看 | 在线视频观看亚洲 | 国产3p视频 | 91麻豆精品国产91久久久使用方法 | 日韩在线一区二区免费 | 亚洲精品 在线视频 | 日韩精品专区在线影院重磅 | 国产中文字幕在线观看 | 日日操日日 | 午夜性福利 | 成人黄色电影视频 | 国内成人av | 青春草免费视频 | 99免费看片 | 亚洲五月综合 | 国产免费又粗又猛又爽 | 免费a级毛片在线看 | 黄色片毛片| 日本久久久久久久久 | 国产精品久久久久久高潮 | av在线播放观看 | 在线黄色毛片 | 黄色a视频 | 在线欧美最极品的av | av中文在线影视 | 精品亚洲成人 | 黄网站污 | 高清av不卡| 国产高清视频网 | 国外成人在线视频网站 | 久草在线资源观看 | 精品久久久久久久 | 毛片视频网址 | 日韩欧美在线视频一区二区 | 久久久久久久久久电影 | 国产理论一区二区三区 | 91资源在线播放 | 中文字幕在线观看91 | 天天色成人网 | 狂野欧美激情性xxxx | 亚洲 成人 欧美 | 国产精品久久久久久久久久三级 | 久久伊人国产精品 | 国产综合在线观看视频 | av软件在线观看 | 免费亚洲视频 | 叶爱av在线 | 欧洲精品二区 | 国产精品成人自产拍在线观看 | 久久人人爽人人爽人人 | 国产老熟| 国产精品9区 | 久久久久久久国产精品 | 亚洲色图22p | 午夜精品久久久久久久99无限制 | 玖草在线观看 | 色婷婷视频在线 | 韩国av在线播放 | 色鬼综合网 | 亚洲一级片在线看 | 三上悠亚一区二区在线观看 | 97国产精品亚洲精品 | 中文字幕国产 | 夜夜骑首页 | 精品中文字幕视频 | 草久草久| 成人免费视频播放 | 色婷婷一 | 91看片黄色| 69精品在线| 毛片网站免费在线观看 | 精品免费一区二区三区 | 欧美日韩国产精品一区 | 欧美日本日韩aⅴ在线视频 插插插色综合 | 国产视频精品久久 | 国产精品欧美久久久久三级 | 看国产黄色大片 | 91男人影院 | www.久久久.com | 久久精品老司机 | 久久伦理电影网 | 成人v| 亚洲三级影院 | 日韩欧美一区二区三区在线 | 日韩激情视频 | 亚洲日韩中文字幕在线播放 | 超碰97中文| 91精品国产亚洲 | av中文字幕在线观看网站 | 黄色a级片在线观看 | 国产精品爽爽久久久久久蜜臀 | 丁香网婷婷| 四虎免费av | 亚洲人xxx | 黄色影院在线免费观看 | 91在线视频在线 | 国产婷婷在线观看 | 成年人网站免费在线观看 | 欧美日韩在线播放 | 午夜精品久久久99热福利 | av成人在线电影 | 久久久www成人免费精品张筱雨 | 在线免费高清 | 国产xxxxx在线观看 | 亚洲综合最新在线 | 最近中文字幕在线中文高清版 | 国产精品一区二区三区免费视频 | 中文字幕一区二区在线观看 | 99久久免费看 | 激情婷婷综合网 | 日操干 | 亚洲一区美女视频在线观看免费 | 成人免费在线网 | 97国产在线观看 | 狠狠操狠狠干天天操 | 日韩在线理论 | www.黄色在线 | 毛片.com | 天天操网址 | 99自拍视频在线观看 | 国产日本亚洲高清 | 99久久99久国产黄毛片 | 国产视频一区在线免费观看 | 91综合久久一区二区 | 久久免费视频一区 | 日韩激情视频 | 香蕉视频亚洲 | 国产91国语对白在线 | 免费看片黄色 | 手机在线小视频 | 精品一区二区亚洲 | 免费看的黄色小视频 | 国产v亚洲v | 中文字幕麻豆 | 日韩黄色一区 | 99热这里只有精品国产首页 | 国产一级免费观看视频 | 婷婷五月在线视频 | 国产精品18久久久久久首页狼 | www.亚洲在线| 最近中文字幕免费观看 | 日韩成人在线一区二区 | 日本性高潮视频 | 97av影院| 亚洲精品免费在线视频 | 日韩高清dvd| 麻豆视频在线观看 | 88av视频 | 五月色丁香 | 天堂av在线网址 | 久久精品一区二区国产 | 女人18精品一区二区三区 | 一区二区三区 中文字幕 | 日韩高清一区 | 嫩草av影院 | 中文字幕二区三区 | 成人a级大片 | 国产无套精品久久久久久 | 亚洲乱码在线 | 嫩草伊人久久精品少妇av | 免费在线国产视频 | 一区二区三区免费在线观看 | 国产综合香蕉五月婷在线 | 国产一区二区精品91 | 中文字幕乱在线伦视频中文字幕乱码在线 | 最新一区二区三区 | 国产精品12| 亚洲,播放 | 久久99久久99精品免观看粉嫩 | 色婷婷在线视频 | 在线免费高清一区二区三区 | 一区二区三区在线观看免费视频 | 天堂av在线网站 | 久久精品激情 | 久久久久久久久久久久亚洲 | 国产一区二区三区免费在线观看 | 狠狠干干| 免费观看丰满少妇做爰 | 日本精品视频网站 | 亚洲成人网在线 | 日韩综合第一页 | 亚洲成人欧美 | av性网站| 国产在线传媒 | 黄色一级大片在线免费看产 | 成人小视频在线观看免费 | 高清国产午夜精品久久久久久 | 在线日韩中文字幕 | 精品国产a | 亚洲精品乱码久久久一二三 | 人人爽人人 | 黄色特级片| 99精品国产视频 | 丁香花五月 | 一二三区在线 | www.天天干.com | 亚洲成人免费在线观看 | 国产淫片| 久草在线在线精品观看 | 日本中文一级片 | 在线观看日韩精品视频 | 国内精品久久久久久久久久清纯 | 日韩国产精品久久久久久亚洲 | 亚洲精品字幕在线 | 国产不卡av在线播放 | 亚洲精品h | 中文在线www | 国产aaa免费视频 | av在线播放国产 | 日韩av网址在线 | 中文字幕久久精品 | 日韩在线观看a | 91精品在线免费观看视频 | 亚洲精品www久久久 www国产精品com | 97电影院在线观看 | 免费看久久久 | 国产精品久久久久久一区二区三区 | 日韩成人一级大片 | 日日操夜夜操狠狠操 | 99久久夜色精品国产亚洲96 | 成人在线视频免费看 | 国产精品久久久久婷婷二区次 | 国产精品一区在线观看 | 中文字幕免费高清 | 在线观看日韩精品视频 | 国产精品无 | 麻豆视频在线观看免费 | 黄色片软件网站 | 国产综合激情 | 国产91勾搭技师精品 | 成年人网站免费观看 | 日韩成人免费在线 | 91cn国产在线 | 最近中文字幕视频网 | 亚洲午夜精品久久久久久久久久久久 | 午夜精品久久久久久久久久久久久久 | 看片网站黄色 | 精一区二区| a级国产乱理伦片在线播放 久久久久国产精品一区 | 毛片网在线 | 国产在线专区 | 午夜性生活 | 久久国产区 | 久久中国精品 | 在线视频久 | 最新真实国产在线视频 | 亚洲欧美日韩精品久久奇米一区 | 一级黄色在线视频 | 99久久er热在这里只有精品66 | 97在线视频免费 | 婷婷激情5月天 | 视频福利在线观看 | 人人人爽 | 国产香蕉视频在线播放 | 亚洲黄色精品 | 91精品久久久久久综合五月天 | 97色婷婷人人爽人人 | 日韩网站免费观看 | 人人舔人人干 | 免费麻豆视频 | 国产在线超碰 | 天天操夜夜操国产精品 | 免费高清无人区完整版 | 久久久久久久国产精品影院 | 国产黄网站在线观看 | 九九交易行官网 | 国产精品自产拍 | 久久精品网站视频 | 91麻豆文化传媒在线观看 | 人人cao | 国产精品免费久久 | 色天堂在线视频 | 欧美激情片在线观看 | 91精品在线免费观看 | 亚洲成人网在线 | 中文字幕一区二区三区在线观看 | 999视频在线播放 | 99操视频 | 黄色毛片一级片 | 青青久草在线 | 成人av免费在线看 | 免费在线播放视频 | 久草在线播放视频 | 久久免费视频7 | 午夜天天操 | 国产视频一二三 | 亚洲欧美成aⅴ人在线观看 四虎在线观看 | 中文字幕亚洲精品日韩 | 国产精久久久久久妇女av | 青青草在久久免费久久免费 | 在线观看成人国产 | 国产五月| 日韩免费电影一区二区三区 | 在线91播放| 欧美激情第一页xxx 午夜性福利 | www夜夜 | 91在线视频观看 | 国产伦精品一区二区三区… | 亚洲精品国产电影 | 最新91在线视频 | 丁香婷婷激情国产高清秒播 | 久久66热这里只有精品 | 日本公妇在线观看 | 一区二区三区在线免费观看视频 | 免费在线观看av不卡 | 亚洲欧美国产精品久久久久 | 国产精品午夜在线观看 | 午夜久操| 中文av资源站 | 激情视频一区二区三区 | 国产69久久精品成人看 | 深夜福利视频一区二区 | 婷婷av网站 | 欧美午夜一区二区福利视频 | 四虎影视www | 色综合久久久久综合99 | 在线国产日本 | 久久国产亚洲精品 | 久9在线 | 亚洲一二视频 | 国产视频久久久久 | 免费在线黄色av | 久久艹精品 | 天天天插| 成 人 黄 色 视频 免费观看 | 人人插人人干 | 天天操天天色综合 | 国产主播大尺度精品福利免费 | 午夜美女av| 日韩欧美69 | 国产二区精品 | 四虎永久免费在线观看 | 欧美老人xxxx18 | 国产精品夜夜夜一区二区三区尤 | 97热久久免费频精品99 | 免费性网站 | 欧美aa在线观看 | 伊人亚洲综合网 | 99久久毛片| 久久这里只有精品1 | 国产精品片 | 爱色婷婷| 国产一级二级三级在线观看 | 999成人网| 天天干天天插伊人网 | 中文字幕有码在线 | 国产精品久久视频 | 三上悠亚一区二区在线观看 | 国产免费观看久久 | 99久久婷婷国产精品综合 | 日韩激情中文字幕 | 最新中文字幕在线观看视频 | 久热精品国产 | 日本成人免费在线观看 | 日韩在线观看视频免费 | 天天操天天操天天操天天操 | 午夜精品三区 | 狠狠操狠狠干天天操 | 日本久久精品视频 | 精品一二区 | 成人免费中文字幕 | 亚洲欧洲精品一区二区精品久久久 | 色婷婷亚洲婷婷 | 一区二区三区四区免费视频 | 国产视频美女 | 免费黄色网址大全 | 精品高清美女精品国产区 | 欧美 日韩精品 | 日本激情中文字幕 | 精品国产欧美一区二区三区不卡 | 午夜精品一区二区国产 | 三级视频国产 | 五月天色综合 | 免费在线观看的av网站 | 天天插日日射 | 国产vs久久 | 成人a在线观看高清电影 | 349k.cc看片app | 开心综合网 | 久久综合婷婷国产二区高清 | 香蕉视频在线网站 | 国产中文在线观看 | 日本韩国精品在线 | 久久久久久久久亚洲精品 | 免费在线观看日韩 | 久久a久久 | 亚洲精品在线观看网站 | 久久久色| 免费看片网址 | 黄色视屏免费在线观看 | 色天天综合久久久久综合片 | 国产黄大片 | 久久综合五月天 | 中文字幕第一 | 天天草天天操 | 女女av在线| 日韩大片在线观看 | 天天曰天天爽 | 美女av电影 | 免费一级黄色 | 在线免费观看视频 | 午夜黄色| 深爱五月激情五月 | www五月婷婷 | 国产精品av在线免费观看 | 亚洲作爱视频 | 天天看天天干天天操 | 国产视频一区在线免费观看 | 日本精品视频一区 | 久久国产精品免费一区 | 黄色成人影院 | 日本一区二区三区免费看 | 国产精品99爱 | 国产免费观看高清完整版 | 夜夜高潮夜夜爽国产伦精品 | 精品国产一区二区三区蜜臀 | 四虎成人精品永久免费av | 麻豆久久 | 福利视频第一页 | 91精品国产99久久久久久红楼 | 色婷婷中文 | 欧美性成人 | 人人插人人草 | 一区二区中文字幕在线播放 | 久久久久免费精品国产小说色大师 | 免费福利在线 | 九九久久免费 | 欧美xxxx性xxxxx高清 | 在线精品视频免费播放 | 丁香花在线观看视频在线 | 91av资源在线 | 在线观看精品视频 | 亚洲91av | 久久久网站 | 国产精品成人a免费观看 | 色偷偷网站视频 | 五月婷在线播放 | 欧洲激情综合 | www天天操 | 手机成人免费视频 | 超碰在线人人草 | 91丨九色丨蝌蚪丨对白 | 青青草久草在线 | 日韩3区| 91精品在线播放 | 欧美日韩国产精品一区二区三区 | 99操视频| 亚洲开心激情 | 91av在线视频播放 | 亚洲精品乱码久久久久久蜜桃欧美 | 最近高清中文字幕在线国语5 | 免费在线成人av电影 | 国产免费黄色 | 国产在线观看你懂得 | 最新av网址在线 | 91伊人久久大香线蕉蜜芽人口 | 久久久精品国产一区二区 | 少妇av片| av久久在线 | 国产剧情一区二区在线观看 | 黄色影院在线免费观看 | 成人网444ppp | 国产专区日韩专区 | 欧美日一级片 | 中文字幕亚洲高清 | 亚洲黄色免费在线看 | 中文字幕资源网 国产 | 激情综合国产 | 99视频精品免费视频 | 深夜免费小视频 | 激情久久久 | 国产精品99久久免费观看 | 久久a国产| 最近高清中文在线字幕在线观看 | 亚洲免费专区 | 国产精品91一区 | 亚洲欧美日本一区二区三区 | 午夜12点 | 日韩欧美视频在线播放 | 欧美精品乱码99久久影院 | 久久久久久久国产精品视频 | 中文字幕一区二区三区乱码不卡 | 日韩在线观看中文字幕 | 欧美在线1区 | 色射爱 | 人人插人人看 | 成人网444ppp | 日本中文字幕高清 | 成年人免费在线播放 | 91成人短视频在线观看 | 奇米影视8888在线观看大全免费 | 99操视频| 91亚洲精 | 91视频免费网址 | 91视频88av | 2023av| 6699私人影院 | 亚洲精品综合在线观看 | 久草在线免 | 亚洲国产影院av久久久久 | 精品成人网 | 九九视频网 | 成年人黄色av | 欧美乱淫视频 | 国产成人久久77777精品 | 96视频免费在线观看 | 婷婷在线色 | 中文字幕视频三区 | 久久亚洲婷婷 | 在线婷婷| 97自拍超碰 | 午夜国产福利在线 | 日本免费久久高清视频 | 欧美日韩电影在线播放 | 国产精品乱码久久久久久1区2区 |