1. 程式人生 > 其它 >c++ :STL

c++ :STL

基礎知識

容器

容器就是一些模板類的集合,不同之處就是容器中封裝的是資料結構

1、序列容器

主要有vector向量容器list列表容器deque雙端佇列容器

元素在容器中是無序的

2、排序容器

包括set容器multiset多重集合容器、map對映容器multimap多重對映容器 

元素預設從小到大排序

3、雜湊容器

包括unordered_set雜湊集合、unirdered_multlist雜湊多重集合、unordered_map 雜湊對映以及 unordered_multimap 雜湊多重對映

元素是未排序的,元素位置由雜湊函式確定

迭代器

根據容器的型別大致分為:輸入迭代器、輸出迭代器、前向迭代器、雙向迭代器、隨機訪問迭代器

 5 種

PS:輸入迭代器和輸出迭代器,不是把陣列和容器當做物件,而是把輸入流/輸出流作為操作物件

1、向前迭代器

假設 p 是一個前向迭代器,則 p 支援 ++p,p++,*p 操作,還可以被複制或賦值,可以用 == 和 != 運算子進行比較。

此外,兩個正向迭代器可以互相賦值。

2、雙向迭代器

雙向迭代器具有正向迭代器的全部功能,除此之外,假設 p 是一個雙向迭代器,則還可以進行 --p 或者 p-- 操作(即一次向後移動一個位置)。

3、隨機訪問迭代器

隨機訪問迭代器具有雙向迭代器的全部功能。除此之外,假設 p 是一個隨機訪問迭代器,i 是一個整型變數或常量,則 p 還支援以下操作:

  • p+=i:使得 p 往後移動 i 個元素。
  • p-=i:使得 p 往前移動 i 個元素。
  • p+i:返回 p 後面第 i 個元素的迭代器。
  • p-i:返回 p 前面第 i 個元素的迭代器。
  • p[i]:返回 p 後面第 i 個元素的引用。

兩個隨機訪問迭代器 p1、p2 還可以用 <、>、<=、>= 運算子進行比較。另外,表示式 p2-p1 也是有定義的,其返回值表示 p2 所指向元素和 p1 所指向元素的序號之差(也可以說是 p2 和 p1 之間的元素個數減一)

不同容器的迭代器:

PS:容器介面卡 stack 和 queue 沒有迭代器,它們包含有一些成員函式,可以用來對元素進行訪問。

定義

四種定義方式:

通過定義以上幾種迭代器,就可以讀取它指向的元素,*迭代器名

就表示迭代器指向的元素。其中,常量迭代器和非常量迭代器的分別在於,通過非常量迭代器還能修改其指向的元素。另外,反向迭代器和正向迭代器的區別在於

  • 對正向迭代器進行 ++ 操作時,迭代器會指向容器中的後一個元素;
  • 而對反向迭代器進行 ++ 操作時,迭代器會指向容器中的前一個元素。

以上 4 種定義迭代器的方式,並不是每個容器都適用。有一部分容器同時支援以上 4 種方式,比如 array、deque、vector;而有些容器只支援其中部分的定義方式,例如 forward_list 容器只支援定義正向迭代器,不支援定義反向迭代器。

反向迭代器:

rbegin()指向最後一個元素,rend()指向第一個元素

begin()指向第一個元素,end()是指向最後一個元素的下一個

舉例:

先了解一下vector中的函式:

  • push_back( ) 成員函式在向量的末尾插入值,如果有必要會擴充套件向量的大小。
  • size( ) 函式顯示向量的大小。
  • begin( ) 函式返回一個指向向量開頭的迭代器。
  • end( ) 函式返回一個指向向量末尾的迭代器。
#include <iostream>
//需要引入 vector 標頭檔案
#include <vector>
using namespace std;
int main()
{
    vector<int> v;
	//v被初始化成有10個元素
	for(int i=0;i<10;i++)
	{
		v.push_back(i);
	}
    cout << "第一種遍歷方法:" << endl;
    //size返回元素個數,像普通陣列一樣使用vector容器
    for (int i = 0; i < v.size(); ++i)
        cout << v[i] <<" "; 
        
    //建立一個正向迭代器,當然,vector也支援其他 3 種定義迭代器的方式
    cout << endl << "第二種遍歷方法:" << endl;
    vector<int>::iterator i;
    //用 != 比較兩個迭代器
    for (i = v.begin(); i != v.end(); ++i)
        cout << *i << " ";
    
    cout << endl << "第三種遍歷方法:" << endl;
    for (i = v.begin(); i < v.end(); ++i) //用 < 比較兩個迭代器
        cout << *i << " ";
   
    cout << endl << "第四種遍歷方法:" << endl;
    i = v.begin();
    while (i < v.end()) { //間隔一個輸出
        cout << *i << " ";
        i += 2; // 隨機訪問迭代器支援 "+= 整數"  的操作
    }
}

轉載:如何能熟練掌握STL

STL初識

STL誕生

  • 長久以來,軟體界一直希望建立一種可重複利用的東西
  • C++的面向物件泛型程式設計思想,目的就是複用性的提升
  • 大多情況下,資料結構和演算法都未能有一套標準,導致被迫從事大量重複工作
  • 為了建立資料結構和演算法的一套標準,誕生了STL

STL基本概念

  • STL(Standard Template Library,標準模板庫)
  • STL 從廣義上分為: 容器(container)、 演算法(algorithm)、 迭代器(iterator)
  • 容器演算法之間通過迭代器進行無縫連線。
  • STL 幾乎所有的程式碼都採用了模板類或者模板函式

STL六大元件

STL大體分為六大元件,分別是:容器、演算法、迭代器、仿函式、介面卡(配接器)、空間配置器

  1. 容器:各種資料結構,如vector、list、deque、set、map等,用來存放資料。
  2. 演算法:各種常用的演算法,如sort、find、copy、for_each等
  3. 迭代器:扮演了容器與演算法之間的膠合劑。
  4. 仿函式:行為類似函式,可作為演算法的某種策略。
  5. 介面卡:一種用來修飾容器或者仿函式或迭代器介面的東西。
  6. 空間配置器:負責空間的配置與管理

STL中容器、演算法和迭代器

1、容器:存放物品

STL容器就是將運用最廣泛的一些資料結構實現出來

常用的資料結構:陣列, 連結串列,樹, 棧, 佇列, 集合, 對映表 等

這些容器分為序列式容器關聯式容器兩種:

序列式容器:強調值的排序,序列式容器中的每個元素均有固定的位置。 關聯式容器: 二叉樹結構,各元素之間沒有嚴格的物理上的順序關係

2、演算法:解決問題的方法

有限的步驟,解決邏輯或數學上的問題,這一門學科我們叫做演算法(Algorithms)

演算法分為: 質變演算法非質變演算法

質變演算法:是指運算過程中會更改區間內的元素的內容。例如拷貝,替換,刪除等等

非質變演算法:是指運算過程中不會更改區間內的元素內容,例如查詢、計數、遍歷、尋找極值等等

3、迭代器:連線容器和演算法的

提供一種方法,使之能夠依序尋訪某個容器所含的各個元素,而又無需暴露該容器的內部表示方式

每個容器都有自己專屬的迭代器

迭代器使用非常類似於指標,初學階段我們可以先理解迭代器為指標

迭代器種類:

常用的容器中的迭代器種類為雙向迭代器隨機訪問迭代器

容器、演算法和迭代器初識

STL中最常用的容器為Vector,可以理解為陣列,下面我們將學習如何向這個容器中插入資料、並遍歷這個容器

1、vector存放內建資料

容器: vector

演算法: for_each

迭代器: vector<int>::iterator

示例:

#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

void MyPrint(int val)
{
    cout << val << endl;
}

void test01() {

    //建立vector容器物件,並且通過模板引數指定容器中存放的資料的型別
    vector<int> v;
    //向容器中放資料
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    v.push_back(40);

    //每一個容器都有自己的迭代器,迭代器是用來遍歷容器中的元素
    //v.begin()返回迭代器,這個迭代器指向容器中第一個資料
    //v.end()返回迭代器,這個迭代器指向容器元素的最後一個元素的下一個位置
    //vector<int>::iterator 拿到vector<int>這種容器的迭代器型別

    vector<int>::iterator pBegin = v.begin();
    vector<int>::iterator pEnd = v.end();

    //第一種遍歷方式:
    while (pBegin != pEnd) {
        cout << *pBegin << endl;
        pBegin++;
    }
    cout << endl;

    //第二種遍歷方式:
    for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
        cout << *it << endl;
    }
    cout << endl;

    //第三種遍歷方式:
    //使用STL提供標準遍歷演算法  標頭檔案 algorithm
    for_each(v.begin(), v.end(), MyPrint);
}

int main() {

    test01();

    system("pause");

    return 0;
}
2、vector存放自定義資料型別 需求:vector中存放自定義資料型別,並列印輸出 例如:
#include <iostream>
#include <vector>
#include <string>

using namespace std;
//自定義資料型別
class Person {
public:
    Person(string name, int age) {
        mName = name;
        mAge = age;
    }
public:
    string mName;
    int mAge;
};
//存放物件
void test01() {

    vector<Person> v;

    //建立資料
    Person p1("aaa", 10);
    Person p2("bbb", 20);
    Person p3("ccc", 30);
    Person p4("ddd", 40);
    Person p5("eee", 50);

    v.push_back(p1);//物件
    v.push_back(p2);
    v.push_back(p3);
    v.push_back(p4);
    v.push_back(p5);

    for (vector<Person>::iterator it = v.begin(); it != v.end(); it++) {
        cout << "Name:" << (*it).mName << " Age:" << (*it).mAge << endl;
    }
}

//放物件指標
void test02() {

    vector<Person*> v;

    //建立資料
    Person p1("aaa", 10);
    Person p2("bbb", 20);
    Person p3("ccc", 30);
    Person p4("ddd", 40);
    Person p5("eee", 50);

    v.push_back(&p1);//物件地址
    v.push_back(&p2);
    v.push_back(&p3);
    v.push_back(&p4);
    v.push_back(&p5);

    for (vector<Person*>::iterator it = v.begin(); it != v.end(); it++) {
        Person * p = (*it);
        cout << "Name:" << p->mName << " Age:" << (*it)->mAge << endl;
    }
}


int main() {

    test01();
    cout << endl;
    test02();

    system("pause");

    return 0;
}

3、vector容器巢狀容器

需求: 容器中巢狀容器,將所有資料進行遍歷

#include <iostream>
#include <vector>

using namespace std;
//容器巢狀容器
void test01() {

    vector< vector<int> >  v;

    vector<int> v1;
    vector<int> v2;
    vector<int> v3;
    vector<int> v4;

    for (int i = 0; i < 4; i++) {
        v1.push_back(i + 1);//1,2,3,4
        v2.push_back(i + 2);//2,3,4,5
        v3.push_back(i + 3);//3,4,5,6
        v4.push_back(i + 4);//4,5,6,7
    }

    //將容器元素插入到vector v中
    v.push_back(v1);
    v.push_back(v2);
    v.push_back(v3);
    v.push_back(v4);


    for (vector<vector<int>>::iterator it = v.begin(); it != v.end(); it++) {

        for (vector<int>::iterator vit = (*it).begin(); vit != (*it).end(); vit++) {
            cout << *vit << " ";
        }
        cout << endl;
    }

}

int main() {

    test01();

    system("pause");

    return 0;
}

STL常用容器

string容器

string基本概念

(1)本質

string是C++風格的字串,而string本質上是一個類

(2)string和char *的區別:

  • char * 是一個指標
  • string是一個類,類內部封裝了char*,管理這個字串,是一個char*型的容器

(3)特點

string 類內部封裝了很多成員方法

例如:查詢find,拷貝copy,刪除delete, 替換replace,插入insert

string管理char*所分配的記憶體,不用擔心複製越界和取值越界等,由類內部進行負責

string建構函式

建構函式原型:

  • string(); //建立一個空的字串 例如: string str;
  • string(const char* s); //使用字串s初始化
  • string(const string& str); //使用一個string物件初始化另一個string物件
  • string(int n, char c); //使用n個字元c初始化
舉例:
#include <string>
#include <iostream>

using namespace std;
//string構造
void test01()
{
    string s1; //建立空字串,呼叫無參建構函式
    cout << "str1 = " << s1 << endl;

    const char* str = "hello world";
    string s2(str); //把char* 轉換成了string

    cout << "str2 = " << s2 << endl;

    string s3(s2); //呼叫拷貝建構函式,string物件初始化string
    cout << "str3 = " << s3 << endl;

    string s4(10, 'a');
    cout << "str4 = " << s4 << endl;
}

int main() {

    test01();

    system("pause");

    return 0;
}

string的多種構造方式沒有可比性,靈活使用即可!

string賦值操作

功能描述:

  • 給string字串進行賦值

賦值的函式原型:

  • string& operator=(const char* s); //char*型別字串 賦值給當前的字串
  • string& operator=(const string &s); //把字串s賦給當前的字串
  • string& operator=(char c); //字元賦值給當前的字串
  • string& assign(const char *s, int n); //把字串s的前n個字元賦給當前的字串
  • string& assign(int n, char c); //用n個字元c賦給當前字串

舉例:

#include <string>
#include <iostream>

using namespace std;
//賦值
void test01()
{
    string str1;
    str1 = "hello world";
    cout << "str1 = " << str1 << endl;

    string str2;
    str2 = str1;
    cout << "str2 = " << str2 << endl;

    string str3;
    str3 = 'a';
    cout << "str3 = " << str3 << endl;

    string str4;
    str4.assign("hello c++");
    cout << "str4 = " << str4 << endl;

    string str5;
    str5.assign("hello c++",5);
    cout << "str5 = " << str5 << endl;


    string str6;
    str6.assign(str5);
    cout << "str6 = " << str6 << endl;

    string str7;
    str7.assign(5, 'x');
    cout << "str7 = " << str7 << endl;
}

int main() {

    test01();

    system("pause");

    return 0;
}

說明:string賦值方式很多,operator=最常用

string字串拼接

功能描述:

  • 實現在字串末尾拼接字串

函式原型:

  • string& operator+=(const char* str); //過載+=操作符
  • string& operator+=(const char c); //過載+=操作符
  • string& operator+=(const string& str); //過載+=操作符
  • string& append(const char *s); //把字串s連線到當前字串結尾
  • string& append(const char *s, int n); //把字串s的前n個字元連線到當前字串結尾
  • string& append(const string &s); //同operator+=(const string& str)
  • string& append(const string &s, int pos, int n);//字串s中從pos開始的n個字元連線到字串結尾
舉例:
#include <string>
#include <iostream>

using namespace std;
//字串拼接
void test01()
{
    string str1 = "";

    str1 += "愛玩遊戲";

    cout << "str1 = " << str1 << endl;

    str1 += ':';

    cout << "str1 = " << str1 << endl;

    string str2 = "LOL DNF";

    str1 += str2;

    cout << "str1 = " << str1 << endl;

    string str3 = "I";
    str3.append(" love ");
    str3.append("game abcde", 4);
    //str3.append(str2);
    str3.append(str2, 4, 3); // 從下標4位置開始 ,擷取3個字元,拼接到字串末尾
    cout << "str3 = " << str3 << endl;
}
int main() {

    test01();

    system("pause");

    return 0;
}

string查詢和替換

功能描述:

  • 查詢:查詢指定字串是否存在
  • 替換:在指定的位置替換字串

函式原型:

  • int find(const string& str, int pos = 0) const; //查詢str第一次出現位置,從pos開始查詢
  • int find(const char* s, int pos = 0) const; //查詢s第一次出現位置,從pos開始查詢
  • int find(const char* s, int pos, int n) const; //從pos位置查詢s的前n個字元第一次位置
  • int find(const char c, int pos = 0) const; //查詢字元c第一次出現位置
  • int rfind(const string& str, int pos = npos) const; //查詢str最後一次位置,從pos開始查詢
  • int rfind(const char* s, int pos = npos) const; //查詢s最後一次出現位置,從pos開始查詢
  • int rfind(const char* s, int pos, int n) const; //從pos查詢s的前n個字元最後一次位置
  • int rfind(const char c, int pos = 0) const; //查詢字元c最後一次出現位置
  • string& replace(int pos, int n, const string& str); //替換從pos開始n個字元為字串str
  • string& replace(int pos, int n,const char* s); //替換從pos開始的n個字元為字串s
舉例:
#include <string>
#include <iostream>

using namespace std;
//查詢和替換
void test01()
{
    //查詢
    string str1 = "abcdefgde";

    int pos = str1.find("de");

    if (pos == -1)
    {
        cout << "未找到" << endl;
    }
    else
    {
        cout << "pos = " << pos << endl;
    }


    pos = str1.rfind("de");

    cout << "pos = " << pos << endl;

}

void test02()
{
    //替換
    string str1 = "abcdefgde";
    str1.replace(1, 3, "1111");

    cout << "str1 = " << str1 << endl;
}

int main() {

    test01();
    test02();

    system("pause");

    return 0;
}

總結:

    • find查詢是從左往後,rfind從右往左
    • find找到字串後返回查詢的第一個字元位置,找不到返回-1
    • replace在替換時,要指定從哪個位置起,多少個字元,替換成什麼樣的字串

string字串比較

功能描述:

  • 字串之間的比較

比較方式:

  • 字串比較是按字元的ASCII碼進行對比

= 返回 0

> 返回 1

< 返回 -1

函式原型:

  • int compare(const string &s) const; //與字串s比較
  • int compare(const char *s) const; //與字串s比較

舉例:

#include <string>
#include <iostream>

using namespace std;
//字串比較
void test01()
{

    string s1 = "hello";
    string s2 = "aello";

    int ret = s1.compare(s2);

    if (ret == 0) {
        cout << "s1 = s2" << endl;
    }
    else if (ret > 0)
    {
        cout << "s1 > s2" << endl;
    }
    else
    {
        cout << "s1 < s2" << endl;
    }

}

int main() {

    test01();

    system("pause");

    return 0;
}

總結:字串對比主要是用於比較兩個字串是否相等,判斷誰大誰小的意義並不是很大

string字元存取

 string中單個字元存取方式有兩種

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

舉例:

#include <string>
#include <iostream>

using namespace std;
void test01()
{
    string str = "hello world";

    for (int i = 0; i < str.size(); i++)
    {
        cout << str[i] << " ";
    }
    cout << endl;

    for (int i = 0; i < str.size(); i++)
    {
        cout << str.at(i) << " ";
    }
    cout << endl;


    //字元修改
    str[0] = 'x';
    str.at(1) = 'x';
    cout << str << endl;

}

int main() {

    test01();

    system("pause");

    return 0;
}

string插入和刪除

功能描述:

  • 對string字串進行插入和刪除字元操作

函式原型:

  • string& insert(int pos, const char* s); //在post處插入字串
  • string& insert(int pos, const string& str); //在post處插入字串
  • string& insert(int pos, int n, char c); //在在post處插入n個字元c
  • string& erase(int pos, int n = npos); //刪除從Pos開始的n個字元
舉例:

#include <string>
#include <iostream>

using namespace std;
//字串插入和刪除
void test01()
{
    string str = "hello";
    str.insert(1, "111");
    cout << str << endl;

    str.erase(1, 3);  //從1號位置開始3個字元
    cout << str << endl;
}

int main() {

    test01();

    system("pause");

    return 0;
}

總結:插入和刪除的起始下標都是從0開始

string子串

功能描述:

  • 從字串中獲取想要的子串

函式原型:

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

舉例:

#include <string>
#include <iostream>

using namespace std;
//子串
void test01()
{
    string str = "abcdefg";
    string subStr = str.substr(1, 3);
    cout << "subStr = " << subStr << endl;

    string email = "[email protected]";
    int pos = email.find("@");
    string username = email.substr(0, pos);
    cout << "username: " << username << endl;

}

int main() {

    test01();

    system("pause");

    return 0;
}

vector容器

vector基本概念

功能:

  • vector資料結構和陣列非常相似,也稱為單端陣列

vector與普通陣列區別:

  • 不同之處在於陣列是靜態空間,而vector可以動態擴充套件

動態擴充套件:

  • 並不是在原空間之後續接新空間,而是找更大的記憶體空間,然後將原資料拷貝新空間,釋放原空間
  • vector容器的迭代器是支援隨機訪問的迭代器

vector建構函式

功能描述:

  • 建立vector容器

函式原型:

  • vector<T> v; //採用模板實現類實現,預設建構函式
  • vector(v.begin(), v.end()); //將v[begin(), end())區間中的元素拷貝給本身。
  • vector(n, elem); //建構函式將n個elem拷貝給本身。
  • vector(const vector &vec); //拷貝建構函式。
舉例:
#include <iostream>
#include <vector>

using namespace std;

void printVector(vector<int>& v) {

    for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
}

void test01()
{
    vector<int> v1; //無參構造
    for (int i = 0; i < 10; i++)
    {
        v1.push_back(i);
    }
    printVector(v1);

    vector<int> v2(v1.begin(), v1.end());//將v1的元素從頭到尾拷貝給v2
    printVector(v2);

    vector<int> v3(10, 100);
    printVector(v3);

    vector<int> v4(v3);
    printVector(v4);
}

int main() {

    test01();

    system("pause");

    return 0;
}

vector的賦值操作

功能描述:

  • 給vector容器進行賦值

函式原型:

  • vector& operator=(const vector &vec);//過載等號操作符
  • assign(beg, end); //將[beg, end)區間中的資料拷貝賦值給本身。
  • assign(n, elem); //將n個elem拷貝賦值給本身。
舉例:
#include <iostream>
#include <vector>

using namespace std;
void printVector(vector<int>& v) {

    for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
}

//賦值操作
void test01()
{
    vector<int> v1; //無參構造
    for (int i = 0; i < 10; i++)
    {
        v1.push_back(i);
    }
    printVector(v1);

    vector<int>v2;
    v2 = v1;
    printVector(v2);

    vector<int>v3;
    v3.assign(v1.begin(), v1.end());
    printVector(v3);

    vector<int>v4;
    v4.assign(10, 100);
    printVector(v4);
}

int main() {

    test01();

    system("pause");

    return 0;
}

總結:vector賦值方式比較簡單,使用operator=,或者assign都可以

vector容量和大小

功能描述:

  • 對vector容器的容量和大小操作

函式原型:

  • empty(); //判斷容器是否為空
  • capacity(); //容器的容量,即容器的資料型別(大小)
  • size(); //返回容器中元素的個數
  • resize(int num); //重新指定容器的長度為num,若容器變長,則以預設值填充新位置。//如果容器變短,則末尾超出容器長度的元素被刪除。
  • resize(int num, elem); //重新指定容器的長度為num,若容器變長,則以elem值填充新位置。 //如果容器變短,則末尾超出容器長度的元素被刪除
舉例:
#include <iostream>
#include <vector>

using namespace std;
void printVector(vector<int>& v) {

    for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
}

void test01()
{
    vector<int> v1;
    for (int i = 0; i < 10; i++)
    {
        v1.push_back(i);
    }
    printVector(v1);
    if (v1.empty())
    {
        cout << "v1為空" << endl;
    }
    else
    {
        cout << "v1不為空" << endl;
        cout << "v1的容量 = " << v1.capacity() << endl;
        cout << "v1的大小 = " << v1.size() << endl;
    }

    //resize 重新指定大小 ,若指定的更大,預設用0填充新位置,可以利用過載版本替換預設填充
    v1.resize(15,10);
    printVector(v1);

    //resize 重新指定大小 ,若指定的更小,超出部分元素被刪除
    v1.resize(5);
    printVector(v1);
}

int main() {

    test01();

    system("pause");

    return 0;
}

vector插入和刪除

功能描述:

  • 對vector容器進行插入、刪除操作

函式原型:

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

#include <iostream>
#include <vector>

using namespace std;
void printVector(vector<int>& v) {

    for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
}

//插入和刪除
void test01()
{
    vector<int> v1;
    //尾插
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(30);
    v1.push_back(40);
    v1.push_back(50);
    printVector(v1);
    //尾刪
    v1.pop_back();
    printVector(v1);
    //插入
    v1.insert(v1.begin(), 100);
    printVector(v1);

    v1.insert(v1.begin(), 2, 1000);
    printVector(v1);

    //刪除
    v1.erase(v1.begin());
    printVector(v1);

    //清空
    v1.erase(v1.begin(), v1.end());
    v1.clear();
    printVector(v1);
}

int main() {

    test01();

    system("pause");

    return 0;
}

vector資料存取

功能描述:

  • 對vector中的資料的存取操作

函式原型:

  • at(int idx); //返回索引 idx 所指的資料
  • operator[]; //返回索引idx所指的資料
  • front(); //返回容器中第一個資料元素
  • back(); //返回容器中最後一個數據元素

舉例:

#include <iostream>
#include <vector>

using namespace std;
void test01()
{
    vector<int>v1;
    for (int i = 0; i < 10; i++)
    {
        v1.push_back(i);
    }

    for (int i = 0; i < v1.size(); i++)
    {
        cout << v1[i] << " ";
    }
    cout << endl;

    for (int i = 0; i < v1.size(); i++)
    {
        cout << v1.at(i) << " ";
    }
    cout << endl;

    cout << "v1的第一個元素為: " << v1.front() << endl;
    cout << "v1的最後一個元素為: " << v1.back() << endl;
}

int main() {

    test01();

    system("pause");

    return 0;
}

vector互換容器

功能描述:

  • 實現兩個容器內元素進行互換

函式原型:

  • swap(vec); // 將vec與本身的元素互換

舉例:

#include <iostream>
#include <vector>

using namespace std;
void printVector(vector<int>& v) {

    for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
}

void test01()
{
    vector<int>v1;
    for (int i = 0; i < 10; i++)
    {
        v1.push_back(i);
    }
    printVector(v1);

    vector<int>v2;
    for (int i = 10; i > 0; i--)
    {
        v2.push_back(i);
    }
    printVector(v2);

    //互換容器
    cout << "互換後" << endl;
    v1.swap(v2);
    printVector(v1);
    printVector(v2);
}

void test02()
{
    vector<int> v;
    for (int i = 0; i < 100000; i++) {
        v.push_back(i);
    }

    cout << "v的容量為:" << v.capacity() << endl;
    cout << "v的大小為:" << v.size() << endl;

    v.resize(3);

    cout << "v的容量為:" << v.capacity() << endl;
    cout << "v的大小為:" << v.size() << endl;

    //收縮記憶體
    vector<int>(v).swap(v); //匿名物件

    cout << "v的容量為:" << v.capacity() << endl;
    cout << "v的大小為:" << v.size() << endl;
}

int main() {

    test01();

    test02();

    system("pause");

    return 0;
}

vector預留空間

功能描述:

  • 減少vector在動態擴充套件容量時的擴充套件次數

函式原型:

  • reserve(int len);//容器預留len個元素長度,預留位置不初始化,元素不可訪問。

舉例:

#include <iostream>
#include <vector>

using namespace std;
void test01()
{
    vector<int> v;

    //預留空間
    v.reserve(100000);

    int num = 0;
    int* p = NULL;
    for (int i = 0; i < 100000; i++) {
        v.push_back(i);
        if (p != &v[0]) {
            p = &v[0];
            num++;
        }
    }

    cout << "num:" << num << endl;
}

int main() {

    test01();

    system("pause");

    return 0;
}

說明:如果資料量較大,可以一開始利用reserve預留空間

deque容器

deque容器基本概念

功能:

  • 雙端陣列,可以對頭端進行插入刪除操作

deque與vector區別:

  • vector對於頭部的插入刪除效率低,資料量越大,效率越低
  • deque相對而言,對頭部的插入刪除速度回比vector快
  • vector訪問元素時的速度會比deque快,這和兩者內部實現有關

deque內部工作原理:

  • deque內部有個中控器,維護每段緩衝區中的內容,緩衝區中存放真實資料
  • 中控器維護的是每個緩衝區的地址,使得使用deque時像一片連續的記憶體空間
  • deque容器的迭代器也是支援隨機訪問的

deque建構函式

功能描述:

  • deque容器構造

函式原型:

  • deque<T> deqT; //預設構造形式
  • deque(beg, end); //建構函式將[beg, end)區間中的元素拷貝給本身。
  • deque(n, elem); //建構函式將n個elem拷貝給本身。
  • deque(const deque &deq); //拷貝建構函式
舉例:
#include <iostream>
#include <deque>
using namespace std;

void printDeque(const deque<int>& d)
{
    for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++) {
        cout << *it << " ";

    }
    cout << endl;
}
//deque構造
void test01() {

    deque<int> d1; //無參建構函式
    for (int i = 0; i < 10; i++)
    {
        d1.push_back(i);
    }
    printDeque(d1);
    deque<int> d2(d1.begin(),d1.end());
    printDeque(d2);

    deque<int>d3(10,100);
    printDeque(d3);

    deque<int>d4 = d3;
    printDeque(d4);
}

int main() {

    test01();

    system("pause");

    return 0;
}

deque賦值操作

功能描述:

  • 給deque容器進行賦值

函式原型:

  • deque& operator=(const deque &deq); //過載等號操作符
  • assign(beg, end); //將[beg, end)區間中的資料拷貝賦值給本身。
  • assign(n, elem); //將n個elem拷貝賦值給本身。

舉例:

#include <iostream>
#include <deque>
using namespace std;

void printDeque(const deque<int>& d)
{
    for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++) {
        cout << *it << " ";

    }
    cout << endl;
}
//賦值操作
void test01()
{
    deque<int> d1;
    for (int i = 0; i < 10; i++)
    {
        d1.push_back(i);
    }
    printDeque(d1);

    deque<int>d2;
    d2 = d1;
    printDeque(d2);

    deque<int>d3;
    d3.assign(d1.begin(), d1.end());
    printDeque(d3);

    deque<int>d4;
    d4.assign(10, 100);
    printDeque(d4);

}

int main() {

    test01();

    system("pause");

    return 0;
}

deque大小操作

功能描述:

  • 對deque容器的大小進行操作

函式原型:

  • deque.empty(); //判斷容器是否為空
  • deque.size(); //返回容器中元素的個數
  • deque.resize(num); //重新指定容器的長度為num,若容器變長,則以預設值填充新位置。 //如果容器變短,則末尾超出容器長度的元素被刪除。
  • deque.resize(num, elem); //重新指定容器的長度為num,若容器變長,則以elem值填充新位置。//如果容器變短,則末尾超出容器長度的元素被刪除。
舉例;
#include <iostream>
#include <deque>
using namespace std;

void printDeque(const deque<int>& d)
{
    for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++) {
        cout << *it << " ";

    }
    cout << endl;
}

//大小操作
void test01()
{
    deque<int> d1;
    for (int i = 0; i < 10; i++)
    {
        d1.push_back(i);
    }
    printDeque(d1);

    //判斷容器是否為空
    if (d1.empty()) {
        cout << "d1為空!" << endl;
    }
    else {
        cout << "d1不為空!" << endl;
        //統計大小
        cout << "d1的大小為:" << d1.size() << endl;
    }

    //重新指定大小
    d1.resize(15, 1);
    printDeque(d1);

    d1.resize(5);
    printDeque(d1);
}

int main() {

    test01();

    system("pause");

    return 0;
}

說明:deque沒有容量的概念

deque 插入和刪除

功能描述:

  • 向deque容器中插入和刪除資料

函式原型:

兩端插入操作:

  • push_back(elem); //在容器尾部新增一個數據
  • push_front(elem); //在容器頭部插入一個數據
  • pop_back(); //刪除容器最後一個數據
  • pop_front(); //刪除容器第一個資料

指定位置操作:

  • insert(pos,elem); //在pos位置插入一個elem元素的拷貝,返回新資料的位置。
  • insert(pos,n,elem); //在pos位置插入n個elem資料,無返回值。
  • insert(pos,beg,end); //在pos位置插入[beg,end)區間的資料,無返回值。
  • clear(); //清空容器的所有資料
  • erase(beg,end); //刪除[beg,end)區間的資料,返回下一個資料的位置。
  • erase(pos); //刪除pos位置的資料,返回下一個資料的位置。
舉例:
#include <iostream>
#include <deque>
using namespace std;

void printDeque(const deque<int>& d)
{
    for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++) {
        cout << *it << " ";

    }
    cout << endl;
}
//兩端操作
void test01()
{
    deque<int> d;
    //尾插
    d.push_back(10);
    d.push_back(20);
    //頭插
    d.push_front(100);
    d.push_front(200);

    printDeque(d);

    //尾刪
    d.pop_back();
    //頭刪
    d.pop_front();
    printDeque(d);
}

//插入
void test02()
{
    deque<int> d;
    d.push_back(10);
    d.push_back(20);
    d.push_front(100);
    d.push_front(200);
    printDeque(d);

    d.insert(d.begin(), 1000);
    printDeque(d);

    d.insert(d.begin(), 2,10000);
    printDeque(d);

    deque<int>d2;
    d2.push_back(1);
    d2.push_back(2);
    d2.push_back(3);

    d.insert(d.begin(), d2.begin(), d2.end());
    printDeque(d);

}

//刪除
void test03()
{
    deque<int> d;
    d.push_back(10);
    d.push_back(20);
    d.push_front(100);
    d.push_front(200);
    printDeque(d);

    d.erase(d.begin());
    printDeque(d);

    d.erase(d.begin(), d.end());
    d.clear();
    printDeque(d);
}

int main() {

    test01();

    test02();

    test03();

    system("pause");

    return 0;
}

說明:插入和刪除提供的位置是迭代器!

deque 資料存取

功能描述:

  • 對deque 中的資料的存取操作

函式原型:

  • at(int idx); //返回索引idx所指的資料
  • operator[]; //返回索引idx所指的資料
  • front(); //返回容器中第一個資料元素
  • back(); //返回容器中最後一個數據元素

舉例:

#include <iostream>
#include <deque>
using namespace std;

void printDeque(const deque<int>& d)
{
    for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++) {
        cout << *it << " ";

    }
    cout << endl;
}

//資料存取
void test01()
{

    deque<int> d;
    d.push_back(10);
    d.push_back(20);
    d.push_front(100);
    d.push_front(200);

    for (int i = 0; i < d.size(); i++) {
        cout << d[i] << " ";
    }
    cout << endl;


    for (int i = 0; i < d.size(); i++) {
        cout << d.at(i) << " ";
    }
    cout << endl;

    cout << "front:" << d.front() << endl;

    cout << "back:" << d.back() << endl;

}

int main() {

    test01();

    system("pause");

    return 0;
}

說明:除了用迭代器獲取deque容器中元素,[ ]和at也可以

deque 排序

功能描述:

  • 利用演算法實現對deque容器進行排序

演算法:

  • sort(iterator beg, iterator end) //對beg和end區間內元素進行排序

舉例:

#include <iostream>
#include <deque>
#include <algorithm>
using namespace std;



void printDeque(const deque<int>& d)
{
    for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++) {
        cout << *it << " ";

    }
    cout << endl;
}

void test01()
{

    deque<int> d;
    d.push_back(10);
    d.push_back(20);
    d.push_front(100);
    d.push_front(200);

    printDeque(d);
    sort(d.begin(), d.end());
    printDeque(d);

}

int main() {

    test01();

    system("pause");

    return 0;
}

說明:sort演算法非常實用,使用時包含標頭檔案 algorithm即可

案例-評委打分

案例描述:

有5名選手:選手ABCDE,10個評委分別對每一名選手打分,去除最高分,去除評委中最低分,取平均分。

實現步驟:

  1. 建立五名選手,放到vector中
  2. 遍歷vector容器,取出來每一個選手,執行for迴圈,可以把10個評分打分存到deque容器中
  3. sort演算法對deque容器中分數排序,去除最高和最低分
  4. deque容器遍歷一遍,累加總分
  5. 獲取平均分
程式:
#include <iostream>
#include <deque>
#include <vector>
#include <algorithm>
#include <ctime>
using namespace std;

//選手類
class Person
{
public:
    Person(string name, int score)
    {
        this->m_Name = name;
        this->m_Score = score;
    }

    string m_Name; //姓名
    int m_Score;  //平均分
};

void createPerson(vector<Person>&v)
{
    string nameSeed = "ABCDE";
    for (int i = 0; i < 5; i++)
    {
        string name = "選手";
        name += nameSeed[i];

        int score = 0;

        Person p(name, score);

        //將建立的person物件 放入到容器中
        v.push_back(p);
    }
}

//打分
void setScore(vector<Person>&v)
{
    for (vector<Person>::iterator it = v.begin(); it != v.end(); it++)
    {
        //將評委的分數 放入到deque容器中
        deque<int>d;
        for (int i = 0; i < 10; i++)
        {
            int score = rand() % 41 + 60;  // 60 ~ 100
            d.push_back(score);
        }

        //cout << "選手: " << it->m_Name << " 打分: " << endl;
        //for (deque<int>::iterator dit = d.begin(); dit != d.end(); dit++)
        //{
        //  cout << *dit << " ";
        //}
        //cout << endl;

        //排序
        sort(d.begin(), d.end());

        //去除最高和最低分
        d.pop_back();
        d.pop_front();

        //取平均分
        int sum = 0;
        for (deque<int>::iterator dit = d.begin(); dit != d.end(); dit++)
        {
            sum += *dit; //累加每個評委的分數
        }

        int avg = sum / d.size();

        //將平均分 賦值給選手身上
        it->m_Score = avg;
    }

}

void showScore(vector<Person>&v)
{
    for (vector<Person>::iterator it = v.begin(); it != v.end(); it++)
    {
        cout << "姓名: " << it->m_Name << " 平均分: " << it->m_Score << endl;
    }
}

int main() {

    //隨機數種子
    srand((unsigned int)time(NULL));

    //1、建立5名選手
    vector<Person>v;  //存放選手容器
    createPerson(v);

    //測試
    //for (vector<Person>::iterator it = v.begin(); it != v.end(); it++)
    //{
    //  cout << "姓名: " << (*it).m_Name << " 分數: " << (*it).m_Score << endl;
    //}

    //2、給5名選手打分
    setScore(v);

    //3、顯示最後得分
    showScore(v);

    system("pause");

    return 0;
}

說明: 選取不同的容器操作資料,可以提升程式碼的效率

stack容器

stack 基本概念

概念:stack是一種先進後出(First In Last Out,FILO)的資料結構,它只有一個出口

棧中只有頂端的元素才可以被外界使用,因此棧不允許有遍歷行為

棧中進入資料稱為 --- 入棧 push

棧中彈出資料稱為 --- 出棧 pop

生活中的棧:

stack 常用介面

功能描述:棧容器常用的對外介面

建構函式:

  • stack<T> stk; //stack採用模板類實現, stack物件的預設構造形式
  • stack(const stack &stk); //拷貝建構函式

賦值操作:

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

資料存取:

  • push(elem); //向棧頂新增元素
  • pop(); //從棧頂移除第一個元素
  • top(); //返回棧頂元素

大小操作:

  • empty(); //判斷堆疊是否為空
  • size(); //返回棧的大小
舉例:
#include <iostream>
#include <stack>
using namespace std;



//棧容器常用介面
void test01()
{
    //建立棧容器 棧容器必須符合先進後出
    stack<int> s;

    //向棧中新增元素,叫做 壓棧 入棧
    s.push(10);
    s.push(20);
    s.push(30);

    while (!s.empty()) {
        //輸出棧頂元素
        cout << "棧頂元素為: " << s.top() << endl;
        //彈出棧頂元素
        s.pop();
        cout << "棧的大小為:" << s.size() << endl;
    }


}

int main() {

    test01();

    system("pause");

    return 0;
}

queue容器

queue 基本概念

概念:Queue是一種先進先出(First In First Out,FIFO)的資料結構,它有兩個出口

佇列容器允許從一端新增元素,從另一端移除元素

佇列中只有隊頭和隊尾才可以被外界使用,因此佇列不允許有遍歷行為

佇列中進資料稱為 --- 入隊 push

佇列中出資料稱為 --- 出隊 pop

生活中的佇列:

queue 常用介面

功能描述:棧容器常用的對外介面

建構函式:

  • queue<T> que; //queue採用模板類實現,queue物件的預設構造形式
  • queue(const queue &que); //拷貝建構函式

賦值操作:

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

資料存取:

  • push(elem); //往隊尾新增元素
  • pop(); //從隊頭移除第一個元素
  • back(); //返回最後一個元素
  • front(); //返回第一個元素

大小操作:

  • empty(); //判斷堆疊是否為空
  • size(); //返回棧的大小
舉例:
#include <iostream>
#include <queue>
#include <string>
using namespace std;

class Person
{
public:
    Person(string name, int age)
    {
        this->m_Name = name;
        this->m_Age = age;
    }

    string m_Name;
    int m_Age;
};

void test01() {

    //建立佇列
    queue<Person> q;

    //準備資料
    Person p1("唐僧", 30);
    Person p2("孫悟空", 1000);
    Person p3("豬八戒", 900);
    Person p4("沙僧", 800);

    //向佇列中新增元素  入隊操作
    q.push(p1);
    q.push(p2);
    q.push(p3);
    q.push(p4);

    //佇列不提供迭代器,更不支援隨機訪問
    while (!q.empty()) {
        //輸出隊頭元素
        cout << "隊頭元素-- 姓名: " << q.front().m_Name
             << " 年齡: "<< q.front().m_Age << endl;

        cout << "隊尾元素-- 姓名: " << q.back().m_Name
             << " 年齡: " << q.back().m_Age << endl;

        cout << endl;
        //彈出隊頭元素
        q.pop();
    }

    cout << "佇列大小為:" << q.size() << endl;
}

int main() {

    test01();

    system("pause");

    return 0;
}

list容器 

list基本概念

功能:將資料進行鏈式儲存

連結串列(list)是一種物理儲存單元上非連續的儲存結構,資料元素的邏輯順序是通過連結串列中的指標連結實現的

連結串列的組成:連結串列由一系列結點組成

結點的組成:一個是儲存資料元素的資料域,另一個是儲存下一個結點地址的指標域

STL中的連結串列是一個雙向迴圈連結串列

由於連結串列的儲存方式並不是連續的記憶體空間,因此連結串列list中的迭代器只支援前移和後移,屬於雙向迭代器

list的優點:

  • 採用動態儲存分配,不會造成記憶體浪費和溢位
  • 連結串列執行插入和刪除操作十分方便,修改指標即可,不需要移動大量元素

list的缺點:

  • 連結串列靈活,但是空間(指標域) 和 時間(遍歷)額外耗費較大

List有一個重要的性質,插入操作和刪除操作都不會造成原有list迭代器的失效,這在vector是不成立的。

總結:STL中List和vector是兩個最常被使用的容器,各有優缺點

list建構函式

功能描述:

  • 建立list容器

函式原型:

  • list<T> lst; //list採用採用模板類實現,物件的預設構造形式:
  • list(beg,end); //建構函式將[beg, end)區間中的元素拷貝給本身。
  • list(n,elem); //建構函式將n個elem拷貝給本身。
  • list(const list &lst); //拷貝建構函式。
舉例:
#include <iostream>
#include <list>
#include <string>
using namespace std;



void printList(const list<int>& L) {

    for (list<int>::const_iterator it = L.begin(); it != L.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
}

void test01()
{
    list<int>L1;
    L1.push_back(10);
    L1.push_back(20);
    L1.push_back(30);
    L1.push_back(40);

    printList(L1);

    list<int>L2(L1.begin(),L1.end());
    printList(L2);

    list<int>L3(L2);
    printList(L3);

    list<int>L4(10, 1000);
    printList(L4);
}

int main() {

    test01();

    system("pause");

    return 0;
}

list 賦值和交換

功能描述:

  • 給list容器進行賦值,以及交換list容器

函式原型:

  • assign(beg, end); //將[beg, end)區間中的資料拷貝賦值給本身。
  • assign(n, elem); //將n個elem拷貝賦值給本身。
  • list& operator=(const list &lst); //過載等號操作符
  • swap(lst); //將lst與本身的元素互換。
舉例:
#include <iostream>
#include <list>
#include <string>
using namespace std;

void printList(const list<int>& L) {

    for (list<int>::const_iterator it = L.begin(); it != L.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
}

//賦值和交換
void test01()
{
    list<int>L1;
    L1.push_back(10);
    L1.push_back(20);
    L1.push_back(30);
    L1.push_back(40);
    printList(L1);

    //賦值
    list<int>L2;
    L2 = L1;
    printList(L2);

    list<int>L3;
    L3.assign(L2.begin(), L2.end());
    printList(L3);

    list<int>L4;
    L4.assign(10, 100);
    printList(L4);

}

//交換
void test02()
{

    list<int>L1;
    L1.push_back(10);
    L1.push_back(20);
    L1.push_back(30);
    L1.push_back(40);

    list<int>L2;
    L2.assign(10, 100);

    cout << "交換前: " << endl;
    printList(L1);
    printList(L2);

    cout << endl;

    L1.swap(L2);

    cout << "交換後: " << endl;
    printList(L1);
    printList(L2);

}

int main() {

    test01();

    test02();

    system("pause");

    return 0;
}

list 大小操作

功能描述:

  • 對list容器的大小進行操作

函式原型:

  • size(); //返回容器中元素的個數
  • empty(); //判斷容器是否為空
  • resize(num); //重新指定容器的長度為num,若容器變長,則以預設值填充新位置。

​ //如果容器變短,則末尾超出容器長度的元素被刪除。

  • resize(num, elem); //重新指定容器的長度為num,若容器變長,則以elem值填充新位置。​ //如果容器變短,則末尾超出容器長度的元素被刪除。
舉例:
#include <iostream>
#include <list>
#include <string>
using namespace std;


void printList(const list<int>& L) {

    for (list<int>::const_iterator it = L.begin(); it != L.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
}

//大小操作
void test01()
{
    list<int>L1;
    L1.push_back(10);
    L1.push_back(20);
    L1.push_back(30);
    L1.push_back(40);
    printList(L1);
    if (L1.empty())
    {
        cout << "L1為空" << endl;
    }
    else
    {
        cout << "L1不為空" << endl;
        cout << "L1的大小為: " << L1.size() << endl;
    }

    //重新指定大小
    L1.resize(10);
    printList(L1);

    L1.resize(2);
    printList(L1);
}

int main() {

    test01();

    system("pause");

    return 0;
}

list 插入和刪除

功能描述:

  • 對list容器進行資料的插入和刪除

函式原型:

  • push_back(elem);//在容器尾部加入一個元素
  • pop_back();//刪除容器中最後一個元素
  • push_front(elem);//在容器開頭插入一個元素
  • pop_front();//從容器開頭移除第一個元素
  • insert(pos,elem);//在pos位置插elem元素的拷貝,返回新資料的位置。
  • insert(pos,n,elem);//在pos位置插入n個elem資料,無返回值。
  • insert(pos,beg,end);//在pos位置插入[beg,end)區間的資料,無返回值。
  • clear();//移除容器的所有資料
  • erase(beg,end);//刪除[beg,end)區間的資料,返回下一個資料的位置。
  • erase(pos);//刪除pos位置的資料,返回下一個資料的位置。
  • remove(elem);//刪除容器中所有與elem值匹配的元素。
舉例:
#include <iostream>
#include <list>
#include <string>
using namespace std;

void printList(const list<int>& L) {

    for (list<int>::const_iterator it = L.begin(); it != L.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
}

//插入和刪除
void test01()
{
    list<int> L;
    //尾插
    L.push_back(10);
    L.push_back(20);
    L.push_back(30);
    //頭插
    L.push_front(100);
    L.push_front(200);
    L.push_front(300);

    printList(L);

    //尾刪
    L.pop_back();
    printList(L);

    //頭刪
    L.pop_front();
    printList(L);

    //插入
    list<int>::iterator it = L.begin();
    L.insert(++it, 1000);
    printList(L);

    //刪除
    it = L.begin();
    L.erase(++it);
    printList(L);

    //移除
    L.push_back(10000);
    L.push_back(10000);
    L.push_back(10000);
    printList(L);
    L.remove(10000);
    printList(L);

    //清空
    L.clear();
    printList(L);
}

int main() {

    test01();

    system("pause");

    return 0;
}

list 資料存取

功能描述:

  • 對list容器中資料進行存取

函式原型:

  • front(); //返回第一個元素。
  • back(); //返回最後一個元素。

舉例:

#include <iostream>
#include <list>
#include <string>
using namespace std;
//資料存取
void test01()
{
    list<int>L1;
    L1.push_back(10);
    L1.push_back(20);
    L1.push_back(30);
    L1.push_back(40);


    //cout << L1.at(0) << endl;//錯誤 不支援at訪問資料
    //cout << L1[0] << endl; //錯誤  不支援[]方式訪問資料
    cout << "第一個元素為: " << L1.front() << endl;
    cout << "最後一個元素為: " << L1.back() << endl;

    //list容器的迭代器是雙向迭代器,不支援隨機訪問
    list<int>::iterator it = L1.begin();
    //it = it + 1;//錯誤,不可以跳躍訪問,即使是+1
}

int main() {

    test01();

    system("pause");

    return 0;
}

說明:list容器中不可以通過[]或者at方式訪問資料 

    list容器的迭代器是雙向迭代器,不支援隨機訪問

list 反轉和排序

功能描述:

  • 將容器中的元素反轉,以及將容器中的資料進行排序

函式原型:

  • reverse(); //反轉連結串列
  • sort(); //連結串列排序(正序,預設為);sort(自定義排序函式)(反序)
舉例:
#include <iostream>
#include <list>
#include <string>
using namespace std;

void printList(const list<int>& L) {

    for (list<int>::const_iterator it = L.begin(); it != L.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
}

bool myCompare(int val1 , int val2)
{
    return val1 > val2;
}

//反轉和排序
void test01()
{
    list<int> L;
    L.push_back(90);
    L.push_back(30);
    L.push_back(20);
    L.push_back(70);
    printList(L);

    //反轉容器的元素
    L.reverse();
    printList(L);

    //排序
    L.sort(); //預設的排序規則 從小到大
    printList(L);

    L.sort(myCompare); //指定規則,從大到小
    printList(L);
}

int main() {

    test01();

    system("pause");

    return 0;
}

排序案例

案例描述:將Person自定義資料型別進行排序,Person中屬性有姓名、年齡、身高

排序規則:按照年齡進行升序,如果年齡相同按照身高進行降序

程式碼:

#include <iostream>
#include <list>
#include <string>
using namespace std;

class Person {
public:
    Person(string name, int age , int height) {
        m_Name = name;
        m_Age = age;
        m_Height = height;
    }

public:
    string m_Name;  //姓名
    int m_Age;      //年齡
    int m_Height;   //身高
};

bool ComparePerson(Person& p1, Person& p2) {
    //12  10
    //12  9
    
    if (p1.m_Age == p2.m_Age) {
        return p1.m_Height  > p2.m_Height;//降序,為0
    }
    //5  10
    //12  9
    else
    {
        return  p1.m_Age < p2.m_Age;//升序,為1
    }
}

void test01() {

    list<Person> L;

    Person p1("劉備", 35 , 175);
    Person p2("曹操", 45 , 180);
    Person p3("孫權", 40 , 170);
    Person p4("趙雲", 25 , 190);
    Person p5("張飛", 35 , 160);
    Person p6("關羽", 35 , 200);

    L.push_back(p1);
    L.push_back(p2);
    L.push_back(p3);
    L.push_back(p4);
    L.push_back(p5);
    L.push_back(p6);

    for (list<Person>::iterator it = L.begin(); it != L.end(); it++) {
        cout << "姓名: " << it->m_Name << " 年齡: " << it->m_Age
             << " 身高: " << it->m_Height << endl;
    }

    cout << "-------------排序後-----------------" << endl;
    L.sort(ComparePerson); //排序

    for (list<Person>::iterator it = L.begin(); it != L.end(); it++) {
        cout << "姓名: " << it->m_Name << " 年齡: " << it->m_Age
             << " 身高: " << it->m_Height << endl;
    }
}

int main() {

    test01();

    system("pause");

    return 0;
}

說明:

  • 對於自定義資料型別,必須要指定排序規則,否則編譯器不知道如何進行排序
  • 高階排序只是在排序規則上再進行一次邏輯規則制定,並不複雜

set/multiset容器

set基本概念

簡介:

  • 所有元素都會在插入時自動被排序

本質:

  • set/multiset屬於關聯式容器,底層結構是用二叉樹實現。

set和multiset區別:

  • set不允許容器中有重複的元素
  • multiset允許容器中有重複的元素

set構造和賦值

功能描述:建立set容器以及賦值

構造:

  • set<T> st; //預設建構函式:
  • set(const set &st); //拷貝建構函式

賦值:

  • set& operator=(const set &st); //過載等號操作符

程式碼:

#include <iostream>
#include <set>
#include <string>
using namespace std;

void printSet(set<int> & s)
{
    for (set<int>::iterator it = s.begin(); it != s.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

//構造和賦值
void test01()
{
    set<int> s1;

    s1.insert(10);
    s1.insert(30);
    s1.insert(20);
    s1.insert(40);
    printSet(s1); //列印

    //拷貝構造
    set<int>s2(s1);
    printSet(s2); //列印

    //賦值
    set<int>s3; //定義
    s3 = s2;    //賦值
    printSet(s3); //列印
}

int main() {

    test01();

    system("pause");

    return 0;
}

說明:

  • set容器插入資料時用insert
  • set容器插入資料的資料會自動排序

set大小和交換

功能描述:

  • 統計set容器大小以及交換set容器

函式原型:

  • size(); //返回容器中元素的數目
  • empty(); //判斷容器是否為空
  • swap(st); //交換兩個集合容器

舉例:

#include <iostream>
#include <set>
#include <string>
using namespace std;

void printSet(set<int> & s)
{
    for (set<int>::iterator it = s.begin(); it != s.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

//大小
void test01()
{

    set<int> s1;

    s1.insert(10);
    s1.insert(30);
    s1.insert(20);
    s1.insert(40);

    if (s1.empty())
    {
        cout << "s1為空" << endl;
    }
    else
    {
        cout << "s1不為空" << endl;
        cout << "s1的大小為: " << s1.size() << endl;
    }

}

//交換
void test02()
{
    set<int> s1;

    s1.insert(10);
    s1.insert(30);
    printSet(s1);
    s1.insert(20);
    printSet(s1);
    s1.insert(40);
    printSet(s1);

    set<int> s2;

    s2.insert(100);
    s2.insert(300);
    printSet(s2);
    s2.insert(200);
    printSet(s2);
    s2.insert(400);
    printSet(s2);

    cout << "交換前" << endl;
    printSet(s1);
    printSet(s2);
    cout << endl;

    cout << "交換後" << endl;
    s1.swap(s2);
    printSet(s1);
    printSet(s2);
}

int main() {

    //test01();

    test02();

    system("pause");

    return 0;
}

set插入和刪除

功能描述:

  • set容器進行插入資料和刪除資料

函式原型:

  • insert(elem); //在容器中插入元素。
  • clear(); //清除所有元素
  • erase(pos); //刪除pos迭代器所指的元素,返回下一個元素的迭代器。
  • erase(beg, end); //刪除區間[beg,end)的所有元素 ,返回下一個元素的迭代器。
  • erase(elem); //刪除容器中值為elem的元素。
程式:
#include <iostream>
#include <set>
#include <string>
using namespace std;

void printSet(set<int> & s)
{
    for (set<int>::iterator it = s.begin(); it != s.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

//插入和刪除
void test01()
{
    set<int> s1;
    //插入
    s1.insert(10);
    s1.insert(30);
    s1.insert(20);
    s1.insert(40);
    printSet(s1);

    //刪除
    s1.erase(s1.begin());
    printSet(s1);

    s1.erase(30);
    printSet(s1);

    //清空
    s1.erase(s1.begin(), s1.end());
    s1.clear();
    printSet(s1);
}

int main() {

    test01();

    system("pause");

    return 0;
}

set查詢和統計

功能描述:

  • 對set容器進行查詢資料以及統計資料

函式原型:

  • find(key); //查詢key是否存在,若存在,返回該鍵的元素的迭代器;若不存在,返回set.end();
  • count(key); //統計key的元素個數
程式:
#include <iostream>
#include <set>
#include <string>
using namespace std;
void printSet(set<int> & s)
{
    for (set<int>::iterator it = s.begin(); it != s.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}
//查詢和統計
void test01()
{
    set<int> s1;
    //插入
    s1.insert(10);
    s1.insert(30);
    s1.insert(20);
    s1.insert(30);
    printSet(s1);//自動刪除重複元素
    //查詢
    set<int>::iterator pos = s1.find(30);

    if (pos != s1.end())
    {
        cout << "找到了元素 : " << *pos << endl;
    }
    else
    {
        cout << "未找到元素" << endl;
    }

    //統計
    int num = s1.count(30);
    cout << "num = " << num << endl;
}

int main() {

    test01();

    system("pause");

    return 0;
}

set和multiset區別

學習目標:

  • 掌握set和multiset的區別

區別:

  • set不可以插入重複資料,而multiset可以
  • set插入資料的同時會返回插入結果,表示插入是否成功
  • multiset不會檢測資料,因此可以插入重複資料

程式:

#include <iostream>
#include <set>
#include <string>
using namespace std;

//set和multiset區別
void test01()
{
    set<int> s;
    pair<set<int>::iterator, bool>  ret = s.insert(10);
    if (ret.second) {
        cout << "第一次插入成功!" << endl;
    }
    else {
        cout << "第一次插入失敗!" << endl;
    }

    ret = s.insert(10);
    if (ret.second) {
        cout << "第二次插入成功!" << endl;
    }
    else {
        cout << "第二次插入失敗!" << endl;
    }

    //multiset
    multiset<int> ms;
    ms.insert(10);
    ms.insert(10);

    for (multiset<int>::iterator it = ms.begin(); it != ms.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
}

int main() {

    test01();

    system("pause");

    return 0;
}

pair對組建立

功能描述:

  • 成對出現的資料,利用對組可以返回兩個資料

兩種建立方式:

    • pair<type, type> p ( value1, value2 );
    • pair<type, type> p = make_pair( value1, value2 );

程式:

#include <iostream>
#include <set>
#include <string>
using namespace std;

//對組建立
void test01()
{
    pair<string, int> p(string("Tom"), 20);
    cout << "姓名: " <<  p.first << " 年齡: " << p.second << endl;

    pair<string, int> p2 = make_pair("Jerry", 10);
    cout << "姓名: " << p2.first << " 年齡: " << p2.second << endl;
}

int main() {

    test01();

    system("pause");

    return 0;
}

set容器排序

學習目標:

  • set容器預設排序規則為從小到大,掌握如何改變排序規則

主要技術點:

利用仿函式,可以改變排序規則 / 可以指定set容器的排序規則

示例一:set存放內建資料型別

程式碼:

#include <iostream>
#include <set>
#include <string>
using namespace std;

class MyCompare
{
public:
    bool operator()(int v1, int v2) {
        return v1 > v2;
    }
};
void test01()
{
    set<int> s1;
    s1.insert(10);
    s1.insert(40);
    s1.insert(20);
    s1.insert(30);
    s1.insert(50);

    //預設從小到大
    for (set<int>::iterator it = s1.begin(); it != s1.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;

    //指定排序規則
    set<int,MyCompare> s2; //仿函式
    s2.insert(10);
    s2.insert(40);
    s2.insert(20);
    s2.insert(30);
    s2.insert(50);

    for (set<int, MyCompare>::iterator it = s2.begin(); it != s2.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
}

int main() {

    test01();

    system("pause");

    return 0;
}

示例二: set存放自定義資料型別

程式:

#include <iostream>
#include <set>
#include <string>
using namespace std;

class Person
{
public:
    Person(string name, int age)
    {
        this->m_Name = name;
        this->m_Age = age;
    }

    string m_Name;
    int m_Age;

};
class comparePerson
{
public:
    bool operator()(const Person& p1, const Person &p2)
    {
        //按照年齡進行排序  降序
        return p1.m_Age > p2.m_Age;
    }
};

void test01()
{
    set<Person, comparePerson> s;

    Person p1("劉備", 23);
    Person p2("關羽", 27);
    Person p3("張飛", 25);
    Person p4("趙雲", 21);

    // 自動排序
    s.insert(p1);
    s.insert(p2);
    s.insert(p3);
    s.insert(p4);

    for (set<Person, comparePerson>::iterator it = s.begin(); it != s.end(); it++)
    {
        cout << "姓名: " << it->m_Name << " 年齡: " << it->m_Age << endl;
    }
}
int main() {

    test01();

    system("pause");

    return 0;
}

map/multiset容器

map基本概念

簡介:

  • map中所有元素都是pair
  • pair中第一個元素為key(鍵值),起到索引作用,第二個元素為value(實值)
  • 所有元素都會根據元素的鍵值自動排序

本質:

  • map/multimap屬於關聯式容器,底層結構是用二叉樹實現。

優點:

  • 可以根據key值快速找到value值

map和multimap區別

  • map不允許容器中有重複key值元素
  • multimap允許容器中有重複key值元素

map構造和賦值

功能描述:

  • 對map容器進行構造和賦值操作

函式原型:

構造:

  • map<T1, T2> mp; //map預設建構函式:
  • map(const map &mp); //拷貝建構函式

賦值:

  • map& operator=(const map &mp); //過載等號操作符

舉例:

#include <iostream>
#include <map>
#include <string>
using namespace std;



void printMap(map<int,int>&m)
{
    for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
    {
        cout << "key = " << it->first << " value = " << it->second << endl;
    }
    cout << endl;
}

void test01()
{
    map<int,int>m; //預設構造
    m.insert(pair<int, int>(1, 10));
    m.insert(pair<int, int>(2, 20));
    m.insert(pair<int, int>(3, 30));
    printMap(m);

    map<int, int>m2(m); //拷貝構造
    printMap(m2);

    map<int, int>m3;
    m3 = m2; //賦值
    printMap(m3);
}

int main() {

    test01();

    system("pause");

    return 0;
}

說明:map中所有元素都是成對出現,插入資料時候要使用對組

map大小和交換

功能描述:

  • 統計map容器大小以及交換map容器

函式原型:

  • size(); //返回容器中元素的數目
  • empty(); //判斷容器是否為空
  • swap(st); //交換兩個集合容器

程式:

#include <iostream>
#include <map>
#include <string>
using namespace std;

void printMap(map<int,int>&m)
{
    for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
    {
        cout << "key = " << it->first << " value = " << it->second << endl;
    }
    cout << endl;
}

void test01()
{
    map<int, int>m;
    m.insert(pair<int, int>(1, 10));
    m.insert(pair<int, int>(2, 20));
    m.insert(pair<int, int>(3, 30));

    if (m.empty())
    {
        cout << "m為空" << endl;
    }
    else
    {
        cout << "m不為空" << endl;
        cout << "m的大小為: " << m.size() << endl;
    }
}


//交換
void test02()
{
    map<int, int>m;
    m.insert(pair<int, int>(1, 10));
    m.insert(pair<int, int>(2, 20));
    m.insert(pair<int, int>(3, 30));

    map<int, int>m2;
    m2.insert(pair<int, int>(4, 100));
    m2.insert(pair<int, int>(5, 200));
    m2.insert(pair<int, int>(6, 300));

    cout << "交換前" << endl;
    printMap(m);
    printMap(m2);

    cout << "交換後" << endl;
    m.swap(m2);
    printMap(m);
    printMap(m2);
}

int main() {

    test01();

    test02();

    system("pause");

    return 0;
}

map插入和刪除

功能描述:

  • map容器進行插入資料和刪除資料

函式原型:

  • insert(elem); //在容器中插入元素。
  • clear(); //清除所有元素
  • erase(pos); //刪除pos迭代器所指的元素,返回下一個元素的迭代器。
  • erase(beg, end); //刪除區間[beg,end)的所有元素 ,返回下一個元素的迭代器。
  • erase(key); //刪除容器中值為key的元素。
程式:
#include <iostream>
#include <map>
#include <string>
using namespace std;

void printMap(map<int,int>&m)
{
    for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
    {
        cout << "key = " << it->first << " value = " << it->second << endl;
    }
    cout << endl;
}

void test01()
{
    //插入
    map<int, int> m;
    //第一種插入方式
    m.insert(pair<int, int>(1, 10));
    //第二種插入方式
    m.insert(make_pair(2, 20));
    //第三種插入方式
    m.insert(map<int, int>::value_type(3, 30));
    //第四種插入方式
    m[4] = 40;
    printMap(m);

    //刪除
    m.erase(m.begin());
    printMap(m);

    m.erase(3);
    printMap(m);

    //清空
    m.erase(m.begin(),m.end());
    m.clear();
    printMap(m);
}

int main() {

    test01();

    system("pause");

    return 0;
}

map查詢和統計

功能描述:

  • 對map容器進行查詢資料以及統計資料

函式原型:

  • find(key); //查詢key是否存在,若存在,返回該鍵的元素的迭代器;若不存在,返回set.end();
  • count(key); //統計key的元素個數

程式:

#include <iostream>
#include <map>
#include <string>
using namespace std;

//查詢和統計
void test01()
{
    map<int, int>m;
    m.insert(pair<int, int>(3, 10));
    m.insert(pair<int, int>(2, 20));
    m.insert(pair<int, int>(3, 30));

    //查詢
    map<int, int>::iterator pos = m.find(2);

    if (pos != m.end())
    {
        cout << "找到了元素 key = " << (*pos).first << " value = " << (*pos).second << endl;
    }
    else
    {
        cout << "未找到元素" << endl;
    }

    //統計
    int num = m.count(3);
    cout << "num = " << num << endl;
}

int main() {

    test01();

    system("pause");

    return 0;
}

總結:

    • 查詢 --- find (返回的是迭代器)
    • 統計 --- count (對於map,結果為0或者1)

map容器排序

學習目標:

  • map容器預設排序規則為 按照key值進行 從小到大排序,掌握如何改變排序規則

主要技術點:

    • 利用仿函式,可以改變排序規則

程式:

#include <iostream>
#include <map>
#include <string>
using namespace std;

class MyCompare {
public:
    bool operator()(int v1, int v2) {
        return v1 > v2;
    }
};

void test01()
{
    //預設從小到大排序
    //利用仿函式實現從大到小排序
    map<int, int, MyCompare> m;

    m.insert(make_pair(1, 10));
    m.insert(make_pair(2, 20));
    m.insert(make_pair(3, 30));
    m.insert(make_pair(4, 40));
    m.insert(make_pair(5, 50));

    for (map<int, int, MyCompare>::iterator it = m.begin(); it != m.end(); it++) {
        cout << "key:" << it->first << " value:" << it->second << endl;
    }
}
int main() {

    test01();

    system("pause");

    return 0;
}

案例-員工分組

案例描述:

  • 公司今天招聘了10個員工(ABCDEFGHIJ),10名員工進入公司之後,需要指派員工在那個部門工作
  • 員工資訊有: 姓名 工資組成;部門分為:策劃、美術、研發
  • 隨機給10名員工分配部門和工資
  • 通過multimap進行資訊的插入 key(部門編號) value(員工)
  • 分部門顯示員工資訊

實現步驟:

  1. 建立10名員工,放到vector中
  2. 遍歷vector容器,取出每個員工,進行隨機分組
  3. 分組後,將員工部門編號作為key,具體員工作為value,放入到multimap容器中
  4. 分部門顯示員工資訊
程式:
#include<iostream>
using namespace std;
#include <vector>
#include <string>
#include <map>
#include <ctime>

/*
- 公司今天招聘了10個員工(ABCDEFGHIJ),10名員工進入公司之後,需要指派員工在那個部門工作
- 員工資訊有: 姓名  工資組成;部門分為:策劃、美術、研發
- 隨機給10名員工分配部門和工資
- 通過multimap進行資訊的插入  key(部門編號) value(員工)
- 分部門顯示員工資訊
*/

#define CEHUA  0
#define MEISHU 1
#define YANFA  2

class Worker
{
public:
    string m_Name;
    int m_Salary;
};

void createWorker(vector<Worker>&v)
{
    string nameSeed = "ABCDEFGHIJ";
    for (int i = 0; i < 10; i++)
    {
        Worker worker;
        worker.m_Name = "員工";
        worker.m_Name += nameSeed[i];

        worker.m_Salary = rand() % 10000 + 10000; // 10000 ~ 19999
        //將員工放入到容器中
        v.push_back(worker);
    }
}

//員工分組
void setGroup(vector<Worker>&v,multimap<int,Worker>&m)
{
    for (vector<Worker>::iterator it = v.begin(); it != v.end(); it++)
    {
        //產生隨機部門編號
        int deptId = rand() % 3; // 0 1 2

        //將員工插入到分組中
        //key部門編號,value具體員工
        m.insert(make_pair(deptId, *it));
    }
}

void showWorkerByGourp(multimap<int,Worker>&m)
{
    // 0  A  B  C   1  D  E   2  F G ...
    cout << "策劃部門:" << endl;

    multimap<int,Worker>::iterator pos = m.find(CEHUA);
    int count = m.count(CEHUA); // 統計具體人數
    int index = 0;
    for (; pos != m.end() && index < count; pos++ , index++)
    {
        cout << "姓名: " << pos->second.m_Name << " 工資: " << pos->second.m_Salary << endl;
    }

    cout << "----------------------" << endl;
    cout << "美術部門: " << endl;
    pos = m.find(MEISHU);
    count = m.count(MEISHU); // 統計具體人數
    index = 0;
    for (; pos != m.end() && index < count; pos++, index++)
    {
        cout << "姓名: " << pos->second.m_Name << " 工資: " << pos->second.m_Salary << endl;
    }

    cout << "----------------------" << endl;
    cout << "研發部門: " << endl;
    pos = m.find(YANFA);
    count = m.count(YANFA); // 統計具體人數
    index = 0;
    for (; pos != m.end() && index < count; pos++, index++)
    {
        cout << "姓名: " << pos->second.m_Name << " 工資: " << pos->second.m_Salary << endl;
    }

}

int main() {

    srand((unsigned int)time(NULL));

    //1、建立員工
    vector<Worker>vWorker;
    createWorker(vWorker);

    //2、員工分組
    multimap<int, Worker>mWorker;
    setGroup(vWorker, mWorker);


    //3、分組顯示員工
    showWorkerByGourp(mWorker);

    ////測試
    //for (vector<Worker>::iterator it = vWorker.begin(); it != vWorker.end(); it++)
    //{
    //  cout << "姓名: " << it->m_Name << " 工資: " << it->m_Salary << endl;
    //}

    system("pause");

    return 0;
}

STL- 函式物件

函式物件

函式物件概念

概念:

  • 過載函式呼叫操作符的類,其物件常稱為函式物件
  • 函式物件使用過載的()時,行為類似函式呼叫,也叫仿函式

本質:

函式物件(仿函式)是一個,不是一個函式

函式物件使用

特點:

  • 函式物件在使用時,可以像普通函式那樣呼叫, 可以有引數,可以有返回值
  • 函式物件超出普通函式的概念,函式物件可以有自己的狀態
  • 函式物件可以作為引數傳遞
程式:
#include<iostream>
using namespace std;
#include <string>

//1、函式物件在使用時,可以像普通函式那樣呼叫, 可以有引數,可以有返回值
class MyAdd
{
public :
    int operator()(int v1,int v2)
    {
        return v1 + v2;
    }
};

void test01()
{
    MyAdd myAdd;
    cout << myAdd(10, 10) << endl;
}

//2、函式物件可以有自己的狀態
class MyPrint
{
public:
    MyPrint()
    {
        count = 0;
    }
    void operator()(string test)
    {
        cout << test << endl;
        count++; //統計使用次數
    }

    int count; //內部自己的狀態
};
void test02()
{
    MyPrint myPrint;
    myPrint("hello world");
    myPrint("hello world");
    myPrint("hello world");
    cout << "myPrint呼叫次數為: " << myPrint.count << endl;
}

//3、函式物件可以作為引數傳遞
void doPrint(MyPrint &mp , string test)
{
    mp(test);
    cout << "myPrint呼叫次數為: " << mp.count << endl;
}

void test03()
{
    MyPrint myPrint;
    doPrint(myPrint, "Hello C++");
}

int main() {

    test01();
    test02();
    test03();

    system("pause");

    return 0;
}

參考

1、C++ STL標準庫基礎

2、C++ STL 教程