STL初識:從零開始的奇幻冒險
1 STL的誕生:一場代碼復用的革命
????????很久很久以前,在編程的世界里,開發者們每天都在重復造輪子。無論是數據結構還是算法,每個人都得從頭開始寫,仿佛在無盡的沙漠中尋找綠洲。直到有一天,C++的面向對象和泛型編程思想橫空出世,帶來了復用性的曙光。于是,STL(Standard Template Library,標準模板庫)應運而生,成為了拯救開發者于水深火熱中的英雄。
2 STL基本概念:容器、算法與迭代器的三角戀
STL,全稱標準模板庫,是C++中的一把瑞士軍刀。它主要由三大核心組成:
-
容器(Container):用來存放數據的各種數據結構,比如數組、鏈表、棧、隊列等。
-
算法(Algorithm):用來處理數據的各種操作,比如排序、查找、遍歷等。
-
迭代器(Iterator):容器和算法之間的橋梁,讓它們能夠無縫連接。
STL的代碼幾乎都是模板類或模板函數,這意味著你可以用一套代碼處理各種數據類型,真正做到“一次編寫,到處運行”。
3 STL六大組件:容器、算法、迭代器、仿函數、適配器、空間配置器
STL不僅僅是一個庫,它更像是一個精密的機器,由六大組件構成:
-
容器:各種數據結構,如
vector
、list
、map
等,用來存放數據。 -
算法:各種常用的操作,如
sort
、find
、copy
等,用來處理數據。 -
迭代器:容器和算法之間的膠水,讓它們能夠協同工作。
-
仿函數:行為像函數的對象,可以作為算法的策略。
-
適配器:用來修飾容器、仿函數或迭代器的接口,讓它們更靈活。
-
空間配置器:負責內存的分配與管理,確保資源的高效利用。
這六大組件共同構成了STL的強大功能,讓開發者能夠輕松應對各種復雜的編程任務。
4 容器、算法、迭代器:STL的三劍客
容器:你可以把它想象成一個魔法背包,里面可以裝各種類型的數據。STL提供了多種容器,比如vector
(動態數組)、list
(鏈表)、map
(映射表)等。這些容器分為兩類:
-
序列式容器:元素按順序排列,比如
vector
和list
。 -
關聯式容器:元素之間沒有嚴格的物理順序,通常基于二叉樹結構,比如
map
和set
。
算法:算法就像是解決問題的魔法咒語。STL提供了大量的算法,比如sort
(排序)、find
(查找)、for_each
(遍歷)等。算法分為兩類:
-
質變算法:會改變容器中的元素,比如
copy
和replace
。 -
非質變算法:不會改變容器中的元素,比如
find
和count
。
迭代器:迭代器就像是魔法棒,讓你能夠遍歷容器中的元素,而不需要知道容器的內部結構。每個容器都有自己的迭代器,迭代器的種類也很多,從簡單的輸入迭代器到功能強大的隨機訪問迭代器,應有盡有。
????????每個容器都有自己專屬的迭代器。迭代器使用非常類似于指針,初學階段我們可以先理解迭代器為指針。
種類 | 功能 | 支持運算 |
---|---|---|
輸入迭代器 | 對數據的只讀訪問 | 只讀,支持++、==、!= |
輸出迭代器 | 對數據的只寫訪問 | 只寫,支持++ |
前向迭代器 | 讀寫操作,并能向前推進迭代器 | 讀寫,支持++、==、!= |
雙向迭代器 | 讀寫操作,并能向前和向后操作 | 讀寫,支持++、-- |
隨機訪問迭代器 | 讀寫操作,可以以跳躍的方式訪問任意數據,功能最強的迭代器 | 讀寫,支持++、--、[n]、-n、<、<=、>、>= |
????????常用的容器中迭代器種類為雙向迭代器和隨機訪問迭代器
5 容器算法迭代器初識:從代碼中感受STL的魅力
5.1 vector存放內置數據類型
vector
是STL中最常用的容器之一,你可以把它看作是一個動態數組。下面是一個簡單的例子,展示了如何向vector
中插入數據并遍歷它:
- 容器: ? ? vector
- 算法: ? ? for_each
- 迭代器: vector<int>::iterator
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm> // 標準算法頭文件// vector存放內置數據類型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);// 通過迭代器訪問容器中的數據// vector<int>::iterator itBegin = v.begin(); //起始迭代器,指向容器中第一個元素// vector<int>::iterator itEnd = v.end(); // 結束迭代器,指向容器中最后一個元素的下一個位置// // 第一種遍歷方式// while (itBegin != itEnd)// {// cout<<*itBegin<<endl;// itBegin++;// }// // 第二種遍歷方式 就是將上面的進行改進優化// for(vector<int>::iterator it=v.begin();it != v.end(); it++)// {// cout<<*it<<endl;// }// 第三種遍歷方式 利用STL提供遍歷算法for_each(v.begin(), v.end(), myPrint);}int main()
{test01();system("pause");return 0;
}
5.2 Vector存放自定義數據類型
vector
不僅可以存放內置數據類型,還可以存放自定義的數據類型。比如,我們可以創建一個Person
類,并將其對象存入vector
中:
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm> // 標準算法頭文件
#include<string>// vector存放自定義數據類型
class Person
{
public:Person(string name, int age){this->m_Name = name;this->m_Age = age;}string m_Name;int m_Age;
};void test01()
{vector<Person>v;Person p1("孫悟空", 25);Person p2("豬八戒", 15);Person p3("鐘無艷", 36);Person p4("蘭陵王", 50);Person p5("安琪拉", 18);// 向容器中添加數據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<<"姓名:"<< (*it).m_Name<<" 年齡:"<<(*it).m_Age<<endl;cout<<"姓名:"<< it->m_Name <<" 年齡:"<< it->m_Age <<endl;}}// 存放自定義數據類型 指針
void test02()
{vector<Person*>v;Person p1("孫悟空", 25);Person p2("豬八戒", 15);Person p3("鐘無艷", 36);Person p4("蘭陵王", 50);Person p5("安琪拉", 18);// 向容器中添加數據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<<"姓名:"<< (*it)->m_Name<<" 年齡:"<<(*it)->m_Age<<endl;// cout<<"姓名:"<< it->m_Name <<" 年齡:"<< it->m_Age <<endl;}
}int main()
{// test01();test02();system("pause");return 0;
}
5.3 Vector容器嵌套容器
STL的容器還可以嵌套使用,比如vector
中可以存放另一個vector
。下面是一個嵌套容器的例子:
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm> // 標準算法頭文件
#include<string>// vector容器嵌套容器
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);v2.push_back(i+2);v3.push_back(i+3);v4.push_back(i+4);}// 將小容器插入大容器中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++){// (*it) ---- 容器 vector<int>for(vector<int>::iterator vit=(*it).begin(); vit!=(*it).end();vit++){cout<<*vit<<" ";}cout<<endl;}}int main()
{test01();system("pause");return 0;
}
結語:STL的奇幻之旅才剛剛開始
????????STL就像是一個充滿魔法的工具箱,里面裝滿了各種強大的工具。通過容器、算法和迭代器的組合,你可以輕松解決各種復雜的編程問題。這只是STL的入門,隨著你深入學習,你會發現它的更多神奇之處。準備好踏上這段奇幻的編程之旅了嗎?STL的世界正等著你去探索!