目錄
一、STL概述
二、STL基本概念
三、STL六大組件
四、string(類)容器
1.string容器基本概念
2.string容器常用操作
五、vector(類模板)容器
1.vector的概述
2.vector的數據結構
3..vector常用的API操作
六、deque容器
1.deque容器基本概念
2.deque容器實現原理
3.deque常用API
七、stack容器
1.stack容器的基本概念
2.stack常用API
八、queue容器
1.queue容器的基本概念
2.queue常用API
九、list容器
1.list容器的基本概念
2.list常用API
十、set/multiset容器
1.set/multiset容器的基本概念
2.set/multiset常用API
3.對組(pair)
十一、map/multimap容器
1.map/multimap容器的基本概念
2.map/multimap常用API
3.multimap案例
STL(Standard Template Library標準模版庫),是惠普實驗室開發的一系列軟件的統稱。
為了建立數據結構和算法的一套標準,降低它們之間的耦合關系,以提升各自的獨立性、彈性、交互操作性(相互合作性,interoprrability),誕生了ST
其實就是提高 代碼復用性,制造出可重復運用的代碼,而不需要自己再去寫已經存在的代碼。??
二、STL基本概念STL從廣義上分為:容器(container)、算法(alhorithm)、迭代器(iterator)
【容器和算法之間通過迭代器進行無縫連接,算法 其實是 通過迭代器 操作 容器數據】
容器、算法、迭代器、仿函數、適配器(配接器)、空間配置器
STL的一個重要特性是 將數據和操作分離,數據由 容器類別 加以管理,操作則由 特定算法 完成。?
1.容器:存放數據
2.算法:操作數據
算法分為 質變算法 和 非質變算法。
質變算法:運算過程中,會更改區間內的元素內容。例如拷貝、替換、刪除等等。
非質變算法:運算過程中,不會更改區間內元素內容。例如查找、計數、遍歷、尋找極值等。
3.迭代器:算法 只能借助迭代器 操作容器數據(容器和迭代器一一對應)。
4.仿函數:為算法提供更多策略
eg:排序函數默認是從小到大排序,用仿函數讓它可以從大到小排序,提供更多的策略。?
5.適配器(配接器):為算法提供更多參數的接口
eg:函數默認是傳1個參數,用適配器讓它可以傳2個參數,這樣的
6.空間配置器:為算法和容器 動態分配、管理空間
最常用的容器是 vector 和 lis t容器。?
四、string(類)容器 1.string容器基本概念c字符串是 以空字符結尾的字符數組,不適合大程序開發,所以c++標準庫定義了一種string類。
?【查找find,拷貝copy,刪除delete,替換replace,插入insert】
?【string管理char*所分配的內存,每一次string的復制、取值都由string類負責維護,不用擔心復制越界和取值越界等 】
2.string容器常用操作(以下都是函數定義。string&是返回值,調用的時候用的是函數名,也就是operator、assign這樣的,懂吧)
【不管什么容器,看到assign就是賦值,operator是運算符重載】
【3.[ ]越界不會拋出異常,at方法會】
【5.find返回第一次出現位置,rfind返回最后一次出現位置,沒找到返回-1;沒傳pos默認從頭開始找】
#include#include//string.h是c的頭文件,string是類的
using namespace std;
#include//input output manipulator:輸入輸出格式控制
void test1()
{
string str;//1.1
cout<< str<< endl;
string str1("hello");//1.3
cout<< str1<< endl;
string str2(5, 'A');//1.4
cout<< str2<< endl;
string str3=str2;//1.2 拷貝構造
cout<< str3<< endl;
string str4;
str4 = "hello";//2.1
cout<< str4<< endl;
str4.assign("world");//2.4
cout<< str4<< endl;
str4 = "W";//2.3
cout<< str4<< endl;
str4.assign("hello",3);//2.5
cout<< str4<< endl;
string str5 = "hello";
str4.assign(str5, 2, 2);//2.8
cout<< str4<< endl;
}
void test2()
{
//3.1+3.2
string str1 = "hello";
cout<< str1[1]<<" "<0)
cout<< "大于"<< endl;
else if (str1.compare(str2)< 0)
cout<< "小于"<< endl;
//>、=、<重載
if (str1==str2)
cout<< "相等"<< endl;
else if (str1>str2)
cout<< "大于"<< endl;
else if (str1
五、vector(類模板)容器
1.vector的概述vector和array的數據安排和操作方式非常相似,兩者的唯一差別在于空間運用的靈活性。 array是靜態空間,vector隨元素的加入,內部會自動擴充空間,以容納新元素。
v.begin():獲取容器的起始迭代器(指向第0個元素)
v.end()? ?:獲取容器的結束迭代器(指向最后一個元素的下一個位置)?
只能尾插尾出
線性連續空間
一旦滿載,vector會開辟 現有空間容量兩倍大小的空間(未雨綢繆機制),將原內容復制到新空間內
3..vector常用的API操作#includeusing namespace std;
#includevoid test1()
{
//類的類型是類,類模板的類型是<類型>vectorv1;
v1.push_back(10);
v1.push_back(20);
v1.push_back(30);
v1.push_back(40);
v1.push_back(50);
//遍歷該容器
//定義一個迭代器iterator 保存起始迭代器
vector::iterator it = v1.begin();
for (; it != v1.end(); it++)
{
//*it==int
cout<< *it<< " ";
}
cout<< endl;
}
void test2()
{
vectorv1;
//可以事先預留足夠空間,省的多次開辟
v1.reserve(1000);//3.6
cout<< "容量:"<::iterator it;
int i = 0;
int count = 0;
for (i = 0; i< 1000; i++)
{
v1.push_back(i);
if (it != v1.begin())//如果開辟空間,v1.begin指向新空間,迭代器仍指向舊空間,v1.begin和迭代器不相等。可以通過這個來判斷是否開辟了空間。
{
count++;
cout<< "第"<< count<< "次開辟空間容量:"<< v1.capacity()<< endl;
it = v1.begin();
}
}
}
void printVectorInt(vector& v)
{
vector::iterator it = v.begin();
for (; it != v.end(); it++)
cout<< *it<< " ";
cout<< endl;
}
void test3()
{
vectorv1(5,100);//1.3
printVectorInt(v1);
vectorv2(v1.begin(), v1.end());//1.2
printVectorInt(v2);
vectorv3;//1.1
//v3=v2; //2.3
//v3.assign(v2.begin(),v2.end()); //2.1
v3.assign(10, 10);
printVectorInt(v3);
v3.swap(v2);//2.4
printVectorInt(v2);
printVectorInt(v3);
vectorv4;
if (v4.empty())//3.2
{
cout<< "空"<< endl;
}
else
cout<< "非空"<< endl;
vectorv5(10,30);
cout<< "容量:"<< v5.capacity()<< " 大小:"<< v5.size()<< endl;//3.5 3.1
printVectorInt(v5);
//v5.resize(15);//過大 補零 3.3
v5.resize(15, 2);//過大 補二 3.4
v5.resize(5);//過小 刪除多余
printVectorInt(v5);
}
void test4()
{
vectorv1;
v1.push_back(10);
v1.push_back(20);
v1.push_back(30);
v1.push_back(40);
v1.push_back(50);//10 20 30 40 50
cout<< "頭元素:"<< v1.front()<< " 尾元素:"<v1;
v1.reserve(1000);
v1.push_back(10);
v1.push_back(20);
v1.push_back(30);
v1.push_back(40);
cout<< "容量:"<< v1.capacity()<< " 大小:"<< v1.size()<< endl;
//resize只能修改大小,不能修改容量
//v1.resize(4);
vector(v1).swap(v1);//vector(v1)為匿名對象,發生拷貝構造,用舊對象v1給新對象賦值(只有size大小的被賦值過去了,而不是capacity大小),
//和v1 swap后,v1指向匿名對象的size大小空間
cout<< "容量:"<< v1.capacity()<< " 大小:"<< v1.size()<< endl;
}
void test6()
{
vectorv1(5, 10);
vectorv2(5, 100);
vectorv3(5, 1000);
//定義一個vector容器存放v1 V2 V3
vector>v;
v.push_back(v1);
v.push_back(v2);
v.push_back(v3);
//遍歷
vector>::iterator it = v.begin();
for (; it != v.end(); it++)
{
//*it==vectorvector::iterator mit = (*it).begin();
for (; mit != (*it).end(); mit++)
{
cout<< *mit<< " ";
}
cout<< endl;
}
}
#include;
void test7()
{
vectorv1;
v1.push_back(20);
v1.push_back(60);
v1.push_back(50);
v1.push_back(30);
v1.push_back(40);
v1.push_back(10);
printVectorInt(v1);
//排序算法
sort(v1.begin(), v1.end());
printVectorInt(v1);
}
#includeclass Person
{
friend bool comparePerson(Person ob1, Person ob2);
friend void printVectorPerson(vector&v);
private:
int num;
string name;
float score;
public:
Person() {}
Person(int num, string name, float score)
{
this->num = num;
this->name = name;
this->score = score;
}
};
void printVectorPerson(vector&v)
{
vector::iterator it = v.begin();
for (; it != v.end(); it++)
{
//*it==Person
cout<< (* it).num<< " "<<(*it).name<<" "<<(*it).score<v1;
v1.push_back(Person(100,"lucy",77.7f));
v1.push_back(Person(103, "bob", 77.7f));
v1.push_back(Person(101, "tom", 77.7f));
v1.push_back(Person(104, "德瑪", 77.7f));
v1.push_back(Person(105, "小法", 77.7f));
printVectorPerson(v1);
//對自定義類型的vector類型排序,需要修改排序規則
sort(v1.begin(),v1.end(),comparePerson);
printVectorPerson(v1);
}
int main(int argc,char *argv[])
{
test8();
return 0;
}
六、deque容器
1.deque容器基本概念double ended queue,雙端隊列
vector與deque容器的大差異:
(1)deque允許在 頭尾兩端 分別做元素的插入和刪除操作,且 所用時間 僅 常數項時間。
【vector也可以頭部插入,但效率太低】
(2)沒有容量的概念。它是動態的,以 分段定量連續空間 組合而成,隨時可以增加一段新的空間并連接起來,不存在容量限制。
【也就是說,
像vector那樣 “空間不足而重新配置一塊更大空間,然后復制元素,再釋放舊空間” 的事情在deque這不存在。
因此deque不需要空間保留(reserve)功能,雖然deque容器也提供了Random Access Iterator,但它的迭代器并不是普通的指針,其復雜度和vector不是一個量級。
因此,除非有必要,盡量使用vector而不是deque。
對deque進行排序操作,為了提高效率。可以將deque完整復制到一個vector中,對vector容器進行排序,再復制回deque。】
array無法擴張
vector尾端假擴張:申請更大空間-->原數據復制新空間-->釋放原空間
deque雙端真擴張
deque采取一塊map作為主控(注意不是STL的map容器,是一小段連續的內存空間),其中每一個元素(結點)都是一個指針,指向另一段連續性內存空間,稱作緩沖區。緩沖區才是deque的存儲空間主體。
Deque由一段段定量連續空間構成。當在deque前端或尾端增加新空間時,便串接一段連續定量的空間。
deque避開了重新配置空間、復制、釋放的輪回,代價就是復雜的迭代器架構和數據結構設計。
#includeusing namespace std;
#includevoid printDequeInt(deque& d)
{
deque::iterator it = d.begin();
for (; it != d.end(); it++)
{
cout<< *it<< " ";
}
cout<< endl;
}
void test1()
{
dequed1;
d1.push_back(1);//4.1
d1.push_back(2);
d1.push_back(3);
d1.push_front(4);//4.2
d1.push_front(5);
d1.push_front(6);
printDequeInt(d1);
cout<< "大小:"<< d1.size()<< endl;
d1.pop_front();//4.4
printDequeInt(d1);
d1.pop_back();//4.3
printDequeInt(d1);
d1.insert(d1.begin() + 1, 3, 100);//6.2
printDequeInt(d1);
}
//8
#include#include
class Person
{
public:
string name;
float score;
public:
Person() {}
Person(string name, float score)
{
this->name = name;
this->score = score;
}
};
void createPerson(vector& v)
{
string tmpName = "ABCDE";
int i = 0;
for (i = 0; i< 5; i++)
{
string name = "選手";
name += tmpName[i];
v.push_back(Person(name, 0.0f));
}
}
void showPerson(vector&v)
{
vector::iterator it = v.begin();
for (; it != v.end(); it++)
{
//*it==Person
cout<< (*it).name<< " "<< (*it).score<< endl;
//以下寫法也可以,但是是把迭代器看成了指針,容易出錯,其他迭代器上可能就不能用了。
//cout<< it->name<< " "<< it->score<< endl;
}
}
void playGame(vector&v)
{
//每人逐個比賽
vector::iterator it = v.begin();
for (; it != v.end(); it++)
{
//定義一個deque容器存放10個評委的分數
dequed;
int i = 0;
for (i = 0; i< 10; i++)
{
d.push_back((float)(rand() % 41 + 60));//rand() % 41:生成0-41間的一個隨機數。
}
//對deque排序
sort(d.begin(), d.end());
//去掉最低最高分
d.pop_back();
d.pop_front();
//求平均分
(*it).score = (float)accumulate(d.begin(), d.end(),0)/d.size();
}
}
#includevoid test2()
{
vectorv;
//srand設置隨機數種子
srand(time(NULL));
//創建五名選手
createPerson(v);
//比賽
playGame(v);
//顯示選手成績
showPerson(v);
}
int main(int argc, char* argv[])
{
test2();
return 0;
}
七、stack容器
1.stack容器的基本概念stack是一種 先進后出 的數據結構,stack容器只能 新增、刪除、取得 棧頂元素。
stack不允許 遍歷,沒有迭代器。【只有一個出口,除了最頂端外,沒有其他方法可以存取stack的其他元素】
queue是一種 先進先出 的數據結構,允許元素從隊尾新增入隊,從隊頭移除出隊。
list容器是一個雙向鏈表。
鏈表是一種物理存儲單元上非連續、非順序的存儲結構,數據元素的邏輯順序是通過鏈表中的指針鏈接次序實現的。
插入和刪除元素是常數時間,無需像靜態鏈表(數組)那樣移動大量元素。
采用動態存儲分配。靈活,但消耗了空間和時間。
十、set/multiset容器 1.set/multiset容器的基本概念list容器的迭代器是雙向迭代器,
- 不支持 +2 這種(隨機訪問迭代器支持,像vector的),支持++(因為++運算符可以重載);
- 不支持 STL提供的算法(STL提供的算法(像sort)只支持隨機訪問迭代器)
【可以寫(對象)h1.sort();】
特征:set的所有元素會根據 鍵值 自動排序。
因為set插入元素就自動排序好了,所以沒有push_back/push_front這種。
修改排序規則:
- 應該在定義類對象時修改,set
【先定義類對象,再插入元素。因為插入時就自動排序了,所以應該在插入之前修改排序規則,也就是在定義類對象時修改】
- 因為在尖括號內,排序規則須是一個類,同時也是一個函數,所以我們用 仿函數 來寫規則。
【仿函數:重載函數調用運算符()的類】
- set存放自定義數據必須修改排序。
【同vector實操最后面出現的。自定義類型不指定排序規則的話,sort不知道你是依據哪個成員變量來排序】
將一對值組合成一個值,這一對值可以具有不同的數據類型,兩個值可以分別用pair的兩個公用屬性 first 和 second 。
模板:template
void test()
{
//方式一:
pairp1(10086,"移動");
pairp2(10010,"聯通");
pairp3(10000,"電信");
//方式二:(推薦)
pairp4=make_pair(9527,"星爺");
cout<
十一、map/multimap容器
1.map/multimap容器的基本概念multimap和map唯一區別在于,multimap鍵值可重復。
map和multimap都是以 紅黑樹 為底層實現機制。?
2.map/multimap常用API你是否還在尋找穩定的海外服務器提供商?創新互聯www.cdcxhl.cn海外機房具備T級流量清洗系統配攻擊溯源,準確流量調度確保服務器高可用性,企業級服務器適合批量采購,新人活動首月15元起,快前往官網查看詳情吧
文章名稱:第十九章-創新互聯
URL分享:http://vcdvsql.cn/article6/jecig.html
成都網站建設公司_創新互聯,為您提供網站改版、響應式網站、動態網站、ChatGPT、企業建站、網站收錄
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯