STL標準庫的使用【2】
我們繼續來介紹STL的相關容器的使用
一、vector
vector 是將元素置於一個動態陣列中加以管理的容器
vector 可以隨機存取元素 (用 [] 操作符 或 at () 方法)
vector 尾部新增或移除元素非常快速,但是在中部和頭部時比較費時
1、vector 資料的訪問
void func1() { vector<int> v; v.push_back(1); v.push_back(2); v.push_back(6); // 第一個元素 cout << v.front() << endl; // 最後一個元素 cout << v.back() << endl; // 返回值是一個引用 v.front() = 10; v.back() = 8; while(!v.empty()) { cout << v.back() << endl; // 刪除最後一個元素,沒有返回值 v.pop_back(); } }
2、遍歷
void printV(vector<int> &v1)
{
for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
3、構造
void func2() { // 定義一個容器,一開始賦予10個物件空間 vector<int> v1(10); cout << "當前元素個數: " << v1.size() << endl; v1[0] = 17; v1.at(1) = 9; v1.push_back(7); cout << "當前元素個數: " << v1.size() << endl; printV(v1); vector<int> v2(10, 2); printV(v2); vector<int> v3 = v2; printV(v3); v3 = v1; printV(v3); vector<int> v4(v3.begin(), v3.begin()+4); printV(v4); }
4、元素刪除
void func3() { vector<int> v1; for (int i = 0; i < 10; i++) { v1.push_back(i); } printV(v1); vector<int>::iterator it = find(v1.begin(), v1.end(), 5); // 單個元素刪除 v1.erase(it); printV(v1); vector<int>::iterator it1 = find(v1.begin(), v1.end(), 3); vector<int>::iterator it2 = find(v1.begin(), v1.end(), 8); // 區間刪除 v1.erase(it1, it2); printV(v1); // 清空容器 // v1.clear(); vector<int> v2; // 空的容器 // 容器交換 v1.swap(v2); v1.push_back(1); v1.push_back(2); v1.push_back(2); v1.push_back(6); v1.push_back(2); v1.push_back(2); //for(vector<int>::iterator it = v1.begin(); it != v1.end();) //{ // if (*it == 2) // { // // 返回指向刪除元素下一個元素的迭代器,需要接收回來 // it = v1.erase(it); // } // else // { // it ++; // } // //} it = v1.begin(); while(it != v1.end()) { if (*it == 2) it = v1.erase(it); else it++; } printV(v1); }
5、元素插入
void func4()
{
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(6);
v.insert(v.begin(), 10);
printV(v);
v.insert(v.begin()+2, 3);
printV(v);
v.insert(v.end(), 4);
printV(v);
vector<int> v1;
v1.insert(v1.begin(), v.begin(), v.end());
printV(v1);
}
二、stack 和 queue
stack是堆疊容器,是一種“先進後出”的容器
queue是佇列容器,是一種“先進先出”的容器
棧這個容器的相關操作
void func1()
{
stack<int> s;
s.push(1);
s.push(5);
s.push(3);
s.push(10); //插入
cout << "棧頂元素: " << s.top() << endl;
cout << "元素個數: " << s.size() << endl;
while (!s.empty())
{
cout << s.top() << endl; // 列印棧頂元素
s.pop();
}
}
佇列的相關操作(和棧類似)
void func2()
{
queue<int> q;
q.push(1);
q.push(10);
q.push(2);
q.push(5);
cout << "隊頭元素: " << q.front() << endl;
cout << "隊尾個數: " << q.back() << endl;
while (!q.empty())
{
cout << q.front() << endl; // 列印棧頂元素
q.pop();
}
}
用兩個棧實現一個佇列
class MyQueue
{
public:
// 出隊
void pop()
{
// 第一種:
// 1、先把 s1 留一個元素, 其他匯入到 s2 中
// 2、s1 出棧
// 3、將 s2 元素再匯入到 s1 中
// 第二種
// 1、先判斷 s2 是否為空
// 2、不為空,s2直接出棧
// 3、如果空,將 s1 留一個元素, 其他匯入到 s2 中
// 4、s1出棧
if(s2.empty())
{
while (s1.size() > 1)
{
s2.push(s1.top());
s1.pop();
}
if (!s1.empty())
s1.pop();
}
else
{
s2.pop();
}
}
// 入隊
void push(int num)
{
// 入 s1
s1.push(num);
}
private:
stack<int> s1;
stack<int> s2;
};
三、list容器
list是一個雙向連結串列容器,可以高效地進行插入和刪除
list不可以隨機的儲存元素
1、list 的賦值 刪除 反序
void func1()
{
list<int> list1;
list1.push_back(1);
list1.push_back(2);
list1.push_back(2);
list1.push_back(2);
list1.push_back(2);
list1.push_back(2);
list1.push_back(2);
list1.push_back(3);
list1.push_front(-1);
list1.push_front(-2);
list1.push_front(-3);
printL(list1);
list<int>::iterator it = list1.begin();
it++;
it++;
// list1.erase(list1.begin(), list1.end()); 刪除區間資料返回下一個資料的位置
//list1.erase(list1.begin(), list1.begin());
//printL(list1);
list1.remove(2); //刪除匹配的元素
printL(list1);
list1.reverse(); //反序列表
printL(list1);
}
2、list 與 迭代器
void func2()
{
vector<int> v(10);
for (int i = 0; i < 10; i++)
{
v[i] = i;
}
// 正向迭代器
for(vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it << " ";
}
cout << endl;
// 反向迭代器
for(vector<int>::reverse_iterator it = v.rbegin(); it != v.rend(); it++)
{
cout << *it << " ";
}
cout << endl;
}
四、優先順序佇列 priority_queue
優先順序佇列內部資料是排完序的,預設是從大到小排序
void func1()
{
// 優先順序佇列內部資料是排完序的,預設是從大到小排序
// priority_queue<int> q;
// priority_queue<int, vector<int>, less<int>> q;
priority_queue<int, vector<int>, greater<int>> q;
q.push(10);
q.push(4);
q.push(2);
q.push(65);
while (!q.empty())
{
cout << q.top() << endl;
q.pop();
}
}
五、set/multiset
set 是一個集合容器,其中所包含的元素是唯一的,集合中的元素按一定順序排列
元素插入過程是按排序規則插入,所以不能指定插入位置
multiset與set的區別:set支援唯一鍵值,每個元素值只能出現一次;
而multiset中同一值可以出現多次。
set.insert(elem); //在容器中插入元素。
set.begin(); //返回容器中第一個資料的迭代器。
set.end(); //返回容器中最後一個數據之後的迭代器。
set.rbegin(); //返回容器中倒數第一個元素的迭代器。
set.rend(); //返回容器中倒數最後一個元素的後面的迭代器。
set<int,less<int> > setIntA; //該容器是按升序方式排列元素。
set<int,greater<int>> setIntB; //該容器是按降序方式排列元素。
六、map/multimap
map的使用 容器:存的是鍵 值 對
map 和 set 一樣會自動排序,是以鍵進行排序 ,map 鍵唯一
通過 map 插入有3種方式
void func1()
{
// 鍵 : int 型別
// 值 : string 型別
// 存學生的 id 和 姓名
map<int, string> m;
// 資料插入:
// 1、通過 pair 鍵值對插入資料
m.insert(pair<int, string>(7, "鄭"));
m.insert(pair<int, string>(8, "王"));
// 2、通過 make pair 構建鍵值對
m.insert(make_pair(5, "周"));
m.insert(make_pair(1, "趙"));
// 3、通過map型別插入
m.insert(map<int, string>::value_type(3, "孫"));
m.insert(map<int, string>::value_type(2, "錢"));
// 4、通過 [] 方式插入資料, []不代表陣列下標,[]內部的值是 map 鍵
m[4] = "李";
m[6] = "吳";
printM(m);
}
還有一種方式是通過 [ ] 方式插入資料,[ ] 不代表陣列下標, [ ] 內部的值是 map 鍵
新增使用者(這個使用者是類呢)
class Student
{
public:
Student(int id, string name)
{
this->id = id;
this->name = name;
}
private:
int id;
string name;
};
class UserManager
{
public:
UserManager()
{
}
// 新增使用者
void add(int id, string name)
{
Student *ps = new Student(id, name);
m.insert(pair<string, Student*>(name, ps));
}
~UserManager()
{
map<string, Student*>::iterator it = m.begin();
while(it != m.end())
{
delete it->second;
it = m.erase(it);
}
}
private:
// 鍵: 學生名字 值 : 學生
map<string, Student*> m;
};
map 迭代器的刪除和查詢
// 迭代器刪除
m.erase(m.begin());
printM(m);
// 通過鍵刪除資料
cout << "-----------------" << endl;
m.erase("趙");
printM(m);
cout << "-----------------" << endl;
// 查詢資料: 查詢通過鍵查詢
map<string, int>::iterator it = m.find("孫");
if (it != m.end())
{
cout << "id = " << it->second << endl;
}
pair<map<string, int>::iterator, map<string, int>::iterator> ret = m.equal_range("孫");
if (ret.first != m.end())
cout << "id = " << ret.first->second << endl;
if (ret.second != m.end())
cout << "id = " << ret.second->second << endl;
}
void func4()
{
map<string, int> m1;
m1.insert(make_pair("王", 8));
// [] 不一定是插入
// 如果鍵存在,修改原鍵的值,如果鍵不存在,就建立一個新的鍵值對
m1["張"] = 10;
}
multimap與map的區別:map支援唯一鍵值,每個鍵只能出現一次;
而multimap中相同鍵可以出現多次。multimap不支援[]操作符。