主頁 >  其他 > 熬夜爆肝!C++核心STL容器知識點匯總整理【3W字干貨預警 建議收藏】

熬夜爆肝!C++核心STL容器知識點匯總整理【3W字干貨預警 建議收藏】

2021-09-04 07:23:48 其他

目錄

  • 前言
    • 1 STL- 常用容器
      • 1.1 vector容器
        • 1.1.1 vector基本概念
        • 1.1.2 vector建構式
        • 1.1.3 vector賦值操作
        • 1.1.4 vector容量和大小
        • 1.1.5 vector插入和洗掉
        • 1.1.6 vector資料存取
        • 1.1.7 vector互換容器
        • 1.1.8 vector預留空間
      • 1.2 deque容器
        • 1.2.1 deque容器基本概念
        • 1.2.2 deque建構式
        • 1.2.3 deque賦值操作
        • 1.2.4 deque大小操作
        • 1.2.5 deque 插入和洗掉
        • 1.2.6 deque 資料存取
        • 1.2.7 deque 排序
      • 1.3 stack容器
        • 1.3.1 stack 基本概念
        • 1.3.2 stack 常用介面
      • 1.4 queue 容器
        • 1.4.1 queue 基本概念
        • 1.4.2 queue 常用介面
      • 1.5 list容器
        • 1.5.1 list基本概念
        • 1.5.2 list建構式
        • 1.5.3 list 賦值和交換
        • 1.5.4 list 大小操作
        • 1.5.5 list 插入和洗掉
        • 1.5.6 list 資料存取
        • 1.5.7 list 反轉和排序
        • 1.5.8 排序案例
      • 1.6 set/ multiset 容器
        • 1.6.1 set基本概念
        • 1.6.2 set構造和賦值
        • 1.6.3 set大小和交換
        • 1.6.4 set插入和洗掉
        • 1.6.5 set查找和統計
        • 1.6.6 set和multiset區別
        • 1.6.7 pair對組創建
        • 1.6.8 set容器排序
      • 1.7 map/ multimap容器
        • 1.7.1 map基本概念
        • 1.7.2 map構造和賦值
        • 1.7.3 map大小和交換
        • 1.7.4 map插入和洗掉
        • 1.7.5 map查找和統計
        • 1.7.6 map容器排序

前言

前段時間有粉絲問我,c++基礎學完了,不知道自己后面該繼續深入學習什么?C++進階要掌握那些知識點?

前幾天,我們已經整理了部分C++進階篇STL知識,C++進階篇STL容器string知識點,今天我們繼續來學習下STL其余常見容器,,一起來看看吧!

以下內容主要根據網上資料進行合并整理,如有侵權,請私信我,

1 STL- 常用容器

1.1 vector容器

1.1.1 vector基本概念

功能:

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

vector與普通陣列區別:

  • 不同之處在于陣列是靜態空間,而vector可以動態擴展

動態擴展:

  • 不是在原空間之后續接新空間,是找更大的記憶體空間,將原資料拷貝新空間,釋放原空間

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-5Lc5FOup-1630623679105)(assets/clip_image002.jpg)]

  • vector容器的迭代器是支持隨機訪問的迭代器

1.1.2 vector建構式

功能描述:

  • 創建vector容器

函式原型:

  • vector v; //采用模板實作類實作,默認建構式
  • vector(v.begin(), v.end()); //將v[begin(), end())區間中的元素拷貝給本身,
  • vector(n, elem); //建構式將n個elem拷貝給本身,
  • vector(const vector &vec); //拷貝建構式,

案例:

#include <vector>

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());
	printVector(v2);

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

int main() {

	test01();

	system("pause");

	return 0;
}

1.1.3 vector賦值操作

功能描述:

  • 給vector容器進行賦值

函式原型:

  • vector& operator=(const vector &vec);//多載等號運算子

  • assign(beg, end); //將[beg, end)區間中的資料拷貝賦值給本身,

  • assign(n, elem); //將n個elem拷貝賦值給本身,

示例:

#include <vector>

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都可以

1.1.4 vector容量和大小

功能描述:

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

函式原型:

  • empty(); //判斷容器是否為空

  • capacity(); //容器的容量

  • size(); //回傳容器中元素的個數

  • resize(int num); //重新指定容器的長度為num,若容器變長,則以默認值填充新位置,

    ? //如果容器變短,則末尾超出容器長度的元素被洗掉,

  • resize(int num, elem); //重新指定容器的長度為num,若容器變長,則以elem值填充新位置,

    ? //如果容器變短,則末尾超出容器長度的元素被洗掉

示例:

#include <vector>

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;
}

總結:

  • 判斷是否為空 — empty
  • 回傳元素個數 — size
  • 回傳容器容量 — capacity
  • 重新指定大小 — resize

1.1.5 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 <vector>

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;
}

總結:

  • 尾插 — push_back
  • 尾刪 — pop_back
  • 插入 — insert (位置迭代器)
  • 洗掉 — erase (位置迭代器)
  • 清空 — clear

1.1.6 vector資料存取

功能描述:

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

函式原型:

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

示例:

#include <vector>

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容器中元素,[ ]和at也可以
  • front回傳容器第一個元素
  • back回傳容器最后一個元素

1.1.7 vector互換容器

功能描述:

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

函式原型:

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

示例:

#include <vector>

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;
}

總結:swap可以使兩個容器互換,可以達到實用的收縮記憶體效果

1.1.8 vector預留空間

功能描述:

  • 減少vector在動態擴展容量時的擴展次數

函式原型:

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

示例:

#include <vector>

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預留空間

1.2 deque容器

1.2.1 deque容器基本概念

功能:

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

deque與vector區別:

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

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-2ttFsUFI-1630623679109)(assets/clip_image002-1547547642923.jpg)]

deque內部作業原理:

deque內部有個中控器,維護每段緩沖區中的內容,緩沖區中存放真實資料

中控器維護的是每個緩沖區的地址,使得使用deque時像一片連續的記憶體空間

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-4952yvMs-1630623679111)(assets/clip_image002-1547547896341.jpg)]

  • deque容器的迭代器也是支持隨機訪問的

1.2.2 deque建構式

功能描述:

  • deque容器構造

函式原型:

  • deque<T> deqT; //默認構造形式
  • deque(beg, end); //建構式將[beg, end)區間中的元素拷貝給本身,
  • deque(n, elem); //建構式將n個elem拷貝給本身,
  • deque(const deque &deq); //拷貝建構式

示例:

#include <deque>

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容器和vector容器的構造方式幾乎一致,靈活使用即可

1.2.3 deque賦值操作

功能描述:

  • 給deque容器進行賦值

函式原型:

  • deque& operator=(const deque &deq); //多載等號運算子

  • assign(beg, end); //將[beg, end)區間中的資料拷貝賦值給本身,

  • assign(n, elem); //將n個elem拷貝賦值給本身,

示例:

#include <deque>

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;
}

1.2.4 deque大小操作

功能描述:

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

函式原型:

  • deque.empty(); //判斷容器是否為空

  • deque.size(); //回傳容器中元素的個數

  • deque.resize(num); //重新指定容器的長度為num,若容器變長,則以默認值填充新位置,

    ? //如果容器變短,則末尾超出容器長度的元素被洗掉,

  • deque.resize(num, elem); //重新指定容器的長度為num,若容器變長,則以elem值填充新位置,

    ? //如果容器變短,則末尾超出容器長度的元素被洗掉,

示例:

#include <deque>

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沒有容量的概念
  • 判斷是否為空 — empty
  • 回傳元素個數 — size
  • 重新指定個數 — resize

1.2.5 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 <deque>

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;
}

總結:

  • 插入和洗掉提供的位置是迭代器!
  • 尾插 — push_back
  • 尾刪 — pop_back
  • 頭插 — push_front
  • 頭刪 — pop_front

1.2.6 deque 資料存取

功能描述:

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

函式原型:

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

示例:

#include <deque>

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也可以
  • front回傳容器第一個元素
  • back回傳容器最后一個元素

1.2.7 deque 排序

功能描述:

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

演算法:

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

示例:

#include <deque>
#include <algorithm>

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;
}

1.3 stack容器

1.3.1 stack 基本概念

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

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-k3AAY7zr-1630623757485)(assets/clip_image002-1547604555425.jpg)]

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

堆疊中進入資料稱為 — 入堆疊 push

堆疊中彈出資料稱為 — 出堆疊 pop

1.3.2 stack 常用介面

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

建構式:

  • stack<T> stk; //stack采用模板類實作, stack物件的默認構造形式
  • stack(const stack &stk); //拷貝建構式

賦值操作:

  • stack& operator=(const stack &stk); //多載等號運算子

資料存取:

  • push(elem); //向堆疊頂添加元素
  • pop(); //從堆疊頂移除第一個元素
  • top(); //回傳堆疊頂元素

大小操作:

  • empty(); //判斷堆疊是否為空
  • size(); //回傳堆疊的大小

示例:

#include <stack>

//堆疊容器常用介面
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;
}

總結:

  • 入堆疊 — push
  • 出堆疊 — pop
  • 回傳堆疊頂 — top
  • 判斷堆疊是否為空 — empty
  • 回傳堆疊大小 — size

1.4 queue 容器

1.4.1 queue 基本概念

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

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-NLlnH6Av-1630623757497)(assets/clip_image002-1547606475892.jpg)]

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

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

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

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

1.4.2 queue 常用介面

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

建構式:

  • queue<T> que; //queue采用模板類實作,queue物件的默認構造形式
  • queue(const queue &que); //拷貝建構式

賦值操作:

  • queue& operator=(const queue &que); //多載等號運算子

資料存取:

  • push(elem); //往隊尾添加元素
  • pop(); //從隊頭移除第一個元素
  • back(); //回傳最后一個元素
  • front(); //回傳第一個元素

大小操作:

  • empty(); //判斷堆疊是否為空
  • size(); //回傳堆疊的大小

示例:

#include <queue>
#include <string>
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;
}

總結:

  • 入隊 — push
  • 出隊 — pop
  • 回傳隊頭元素 — front
  • 回傳隊尾元素 — back
  • 判斷隊是否為空 — empty
  • 回傳佇列大小 — size

1.5 list容器

1.5.1 list基本概念

**功能:**將資料進行鏈式存盤

鏈表(list)是一種物理存盤單元上非連續的存盤結構,資料元素的邏輯順序是通過鏈表中的指標鏈接實作的

鏈表的組成:鏈表由一系列結點組成

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

STL中的鏈表是一個雙向回圈鏈表

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-IGnLWsXo-1630623757504)(assets/clip_image002-1547608564071.jpg)]

由于鏈表的存盤方式并不是連續的記憶體空間,因此鏈表list中的迭代器只支持前移和后移,屬于雙向迭代器

list的優點:

  • 采用動態存盤分配,不會造成記憶體浪費和溢位
  • 鏈表執行插入和洗掉操作十分方便,修改指標即可,不需要移動大量元素

list的缺點:

  • 鏈表靈活,但是空間(指標域) 和 時間(遍歷)額外耗費較大

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

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

1.5.2 list建構式

功能描述:

  • 創建list容器

函式原型:

  • list<T> lst; //list采用采用模板類實作,物件的默認構造形式:
  • list(beg,end); //建構式將[beg, end)區間中的元素拷貝給本身,
  • list(n,elem); //建構式將n個elem拷貝給本身,
  • list(const list &lst); //拷貝建構式,

示例:

#include <list>

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;
}

1.5.3 list 賦值和交換

功能描述:

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

函式原型:

  • assign(beg, end); //將[beg, end)區間中的資料拷貝賦值給本身,
  • assign(n, elem); //將n個elem拷貝賦值給本身,
  • list& operator=(const list &lst); //多載等號運算子
  • swap(lst); //將lst與本身的元素互換,

示例:

#include <list>

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;
}

1.5.4 list 大小操作

功能描述:

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

函式原型:

  • size(); //回傳容器中元素的個數

  • empty(); //判斷容器是否為空

  • resize(num); //重新指定容器的長度為num,若容器變長,則以默認值填充新位置,

    ? //如果容器變短,則末尾超出容器長度的元素被洗掉,

  • resize(num, elem); //重新指定容器的長度為num,若容器變長,則以elem值填充新位置,

      				    //如果容器變短,則末尾超出容器長度的元素被洗掉,
    

示例:

#include <list>

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);

	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;
}

總結:

  • 判斷是否為空 — empty
  • 回傳元素個數 — size
  • 重新指定個數 — resize

1.5.5 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 <list>

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;
}

總結:

  • 尾插 — push_back
  • 尾刪 — pop_back
  • 頭插 — push_front
  • 頭刪 — pop_front
  • 插入 — insert
  • 洗掉 — erase
  • 移除 — remove
  • 清空 — clear

1.5.6 list 資料存取

功能描述:

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

函式原型:

  • front(); //回傳第一個元素,
  • back(); //回傳最后一個元素,

示例:

#include <list>

//資料存取
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方式訪問資料
  • 回傳第一個元素 — front
  • 回傳最后一個元素 — back

1.5.7 list 反轉和排序

功能描述:

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

函式原型:

  • reverse(); //反轉鏈表
  • sort(); //鏈表排序

示例:

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;
}

總結:

  • 反轉 — reverse
  • 排序 — sort (成員函式)

1.5.8 排序案例

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

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

示例:

#include <list>
#include <string>
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) {

	if (p1.m_Age == p2.m_Age) {
		return p1.m_Height  > p2.m_Height;
	}
	else
	{
		return  p1.m_Age < p2.m_Age;
	}

}

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;
}
  • 對于自定義資料型別,必須要指定排序規則,否則編譯器不知道如何進行排序

  • 高級排序只是在排序規則上再進行一次邏輯規則制定,并不復雜

1.6 set/ multiset 容器

1.6.1 set基本概念

簡介:

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

本質:

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

set和multiset區別

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

1.6.2 set構造和賦值

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

構造:

  • set<T> st; //默認建構式:
  • set(const set &st); //拷貝建構式

賦值:

  • set& operator=(const set &st); //多載等號運算子

示例:

#include <set>

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容器插入資料的資料會自動排序

1.6.3 set大小和交換

功能描述:

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

函式原型:

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

示例:

#include <set>

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);
	s1.insert(20);
	s1.insert(40);

	set<int> s2;

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

	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;
}
  • 統計大小 — size
  • 判斷是否為空 — empty
  • 交換容器 — swap

1.6.4 set插入和洗掉

功能描述:

  • set容器進行插入資料和洗掉資料

函式原型:

  • insert(elem); //在容器中插入元素,
  • clear(); //清除所有元素
  • erase(pos); //洗掉pos迭代器所指的元素,回傳下一個元素的迭代器,
  • erase(beg, end); //洗掉區間[beg,end)的所有元素 ,回傳下一個元素的迭代器,
  • erase(elem); //洗掉容器中值為elem的元素,

示例:

#include <set>

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;
}
  • 插入 — insert
  • 洗掉 — erase
  • 清空 — clear

1.6.5 set查找和統計

功能描述:

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

函式原型:

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

示例:

#include <set>

//查找和統計
void test01()
{
	set<int> s1;
	//插入
	s1.insert(10);
	s1.insert(30);
	s1.insert(20);
	s1.insert(40);
	
	//查找
	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;
}
  • 查找 — find (回傳的是迭代器)
  • 統計 — count (對于set,結果為0或者1)

1.6.6 set和multiset區別

區別:

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

示例:

#include <set>

//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;
}
  • 如果不允許插入重復資料可以利用set
  • 如果需要插入重復資料利用multiset

1.6.7 pair對組創建

功能描述:

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

創建方式:

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

示例:

#include <string>

//對組創建
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;
}

1.6.8 set容器排序

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

#include <set>

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容器的排序規則

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

#include <set>
#include <string>

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;
}

對于自定義資料型別,set必須指定排序規則才可以插入資料

1.7 map/ multimap容器

1.7.1 map基本概念

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

本質:

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

優點:

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

map和multimap區別

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

1.7.2 map構造和賦值

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

函式原型:

構造:

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

賦值:

  • map& operator=(const map &mp); //多載等號運算子

示例:

#include <map>

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中所有元素都是成對出現,插入資料時候要使用對組

1.7.3 map大小和交換

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

函式原型:

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

示例:

#include <map>

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;
}
  • 統計大小 — size
  • 判斷是否為空 — empty
  • 交換容器 — swap

1.7.4 map插入和洗掉

功能描述:

  • map容器進行插入資料和洗掉資料

函式原型:

  • insert(elem); //在容器中插入元素,
  • clear(); //清除所有元素
  • erase(pos); //洗掉pos迭代器所指的元素,回傳下一個元素的迭代器,
  • erase(beg, end); //洗掉區間[beg,end)的所有元素 ,回傳下一個元素的迭代器,
  • erase(key); //洗掉容器中值為key的元素,

示例:

#include <map>

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;
}
  • 插入 — insert
  • 洗掉 — erase
  • 清空 — clear

1.7.5 map查找和統計

功能描述:

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

函式原型:

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

示例:

#include <map>

//查找和統計
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));

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

	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)

1.7.6 map容器排序

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

示例:

#include <map>

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;
}
  • 利用仿函式可以指定map容器的排序規則
  • 對于自定義資料型別,map必須要指定排序規則,同set容器

至此,C++中的常用STL容器就全部介紹結束了,
在這里插入圖片描述
若本篇內容對您有所幫助,請三連點贊,關注,收藏支持下,

創作不易,白嫖不好,各位的支持和認可,就是我創作的最大動力,我們下篇文章見!

Dragon少年 | 文

如果本篇博客有任何錯誤,請批評指教,不勝感激 !

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/297295.html

標籤:其他

上一篇:?超詳細圖解Linux安裝?

下一篇:??思維導圖整理大廠面試高頻陣列9: 洗掉重復元素的通解問題, 力扣26/80??

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more