STL初識
STL初識
1 STL的誕生
- 長久以來,軟件界一直希望建立一種可重複利用的東西
- C++的面向對象和泛型編程思想,目的就是複用性的提升
- 大多情況下,數據結構和算法都未能有一套標準,導致被迫從事大量重複工作
- 爲了建立數據結構和算法的一套標準,誕生了STL
2 STL基本概念
- STL(Standard Template Library,標準模板庫)
- STL 從廣義上分爲: 容器(container) 算法(algorithm) 迭代器(iterator)
- 容器和算法之間通過迭代器進行無縫連接。
- STL 幾乎所有的代碼都採用了模板類或者模板函數
3 STL六大組件
STL大體分爲六大組件,分別是:容器、算法、迭代器、仿函數、適配器(配接器)、空間配置器
- 容器:各種數據結構,如vector、list、deque、set、map等,用來存放數據。
- 算法:各種常用的算法,如sort、find、copy、for_each等
- 迭代器:扮演了容器與算法之間的膠合劑。
- 仿函數:行爲類似函數,可作爲算法的某種策略。
- 適配器:一種用來修飾容器或者仿函數或迭代器接口的東西。
- 空間配置器:負責空間的配置與管理。
4 STL中容器、算法、迭代器
容器:置物之所也
STL容器就是將運用最廣泛的一些數據結構實現出來
常用的數據結構:數組, 鏈表,樹, 棧, 隊列, 集合, 映射表 等
這些容器分爲序列式容器和關聯式容器兩種:
序列式容器:強調值的排序,序列式容器中的每個元素均有固定的位置。
關聯式容器:二叉樹結構,各元素之間沒有嚴格的物理上的順序關係
算法:問題之解法也
有限的步驟,解決邏輯或數學上的問題,這一門學科我們叫做算法(Algorithms)
算法分爲:質變算法和非質變算法。
質變算法:是指運算過程中會更改區間內的元素的內容。例如拷貝,替換,刪除等等
非質變算法:是指運算過程中不會更改區間內的元素內容,例如查找、計數、遍歷、尋找極值等等
迭代器:容器和算法之間粘合劑
提供一種方法,使之能夠依序尋訪某個容器所含的各個元素,而又無需暴露該容器的內部表示方式。
每個容器都有自己專屬的迭代器
迭代器使用非常類似於指針,初學階段我們可以先理解迭代器爲指針
迭代器種類:
常用的容器中迭代器種類爲雙向迭代器,和隨機訪問迭代器
5 容器算法迭代器初識
瞭解STL中容器、算法、迭代器概念之後,我們利用代碼感受STL的魅力
STL中最常用的容器爲Vector,可以理解爲數組,下面我們將學習如何向這個容器中插入數據、並遍歷這個容器
5.1 vector存放內置數據類型
第一種vector數據遍歷方法while
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> v;
v.push_back(10);
v.push_back(20);
v.push_back(30);
vector<int>::iterator it_begin = v.begin();
vector<int>::iterator it_end = v.end();
while (it_begin != it_end)
{
cout << *it_begin << endl;
it_begin++;
}
system("pause");
return 0;
}
第二種vector數據遍歷方法for循環
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> v;
v.push_back(10);
v.push_back(20);
v.push_back(30);
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it <<endl;
}
system("pause");
return 0;
}
第三種for_each算法遍歷
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void test1(int val)
{
cout << val << endl;
}
int main()
{
vector<int> v;
v.push_back(10);
v.push_back(20);
v.push_back(30);
for_each(v.begin(), v.end(), test1); //test傳入形參爲*iterator
system("pause");
return 0;
}
其中for_each:
// FUNCTION TEMPLATE for_each
template<class _InIt,
class _Fn> inline
_Fn for_each(_InIt _First, _InIt _Last, _Fn _Func)
{ // perform function for each element [_First, _Last)
_Adl_verify_range(_First, _Last);
auto _UFirst = _Get_unwrapped(_First);
const auto _ULast = _Get_unwrapped(_Last);
for (; _UFirst != _ULast; ++_UFirst)
{
_Func(*_UFirst);//形參爲*iterator
}
return (_Func);
}
運行結果:
5.2 Vector存放自定義數據類型
學習目標:vector中存放自定義數據類型,並打印輸出
#include <iostream>
#include <vector>
#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 test2()
{
vector<person> v;
person v1("wangshuai", 24);
person v2("liangpeng", 24);
v.push_back(v1);
v.push_back(v2);
for (vector<person>::iterator it = v.begin(); it != v.end(); it++)
{
cout << "name:" << (*it).m_name << endl;
cout << "age:" << (*it).m_age << endl;
cout << "-------------" << endl;
}
}
//存放對象指針
void test3()
{
vector<person*> v;
person p1("ws", 22);
person p2("lp", 23);
v.push_back(&p1);
v.push_back(&p2);
for (vector<person*>::iterator i = v.begin(); i != v.end(); i++)
{
cout << "name:" << (*i)->m_name << endl;
cout << "age:" << (*i)->m_age << endl;
cout << "---------------" << endl;
}
}
int main()
{
test2();
test3();
system("pause");
return 0;
}
運行結果
5.3 Vector容器嵌套容器
學習目標:容器中嵌套容器,我們將所有數據進行遍歷輸出
#include <iostream>
#include <vector>
using namespace std;
void test4()
{
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++)
{
for (vector<int>::iterator it1 = (*it).begin(); it1 != (*it).end(); it1++)
{
cout << *it1 << "";
}
cout << endl;
}
}
int main()
{
test4();
system("pause");
return 0;
}
運行結果