STL 代碼示例
1、迭代器
- 迭代器可以將任意的容器抽象成一個序列,可以使用迭代器遍歷容器中的元素
- 迭代器設(shè)計的目的是為了解決容器與算法之間的耦合問題,與指針類似,可以通過迭代器訪問容器中的元素
- 迭代器的聲明方式為:容器類型::iterator 變量名稱,可以理解為一個普通的指針,比如:
- std::vector<int>::iterator it;
- std::list<int>::iterator it;
- std::map<int, int>::iterator it;
- std::set<int>::iterator it;
代碼:
/*
* 迭代器示例
* 迭代器可以將任意的容器抽象成一個序列,可以使用迭代器遍歷容器中的元素
* 迭代器設(shè)計的目的是為了解決容器與算法之間的耦合問題,與指針類似,可以通過迭代器訪問容器中的元素
* 迭代器的聲明方式為:容器類型::iterator,比如:
std::vector<int>::iterator it;
std::list<int>::iterator it;
std::map<int, int>::iterator it;
std::set<int>::iterator it;
*/
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <list>
// 打印vector元素
void printVec(const std::vector<int> &v)
{
std::cout << "[";
for (const auto &e : v)
std::cout << e << " ";
std::cout << "]" << std::endl;
}
void test1()
{
std::cout << "test1 ======================" << std::endl;
std::vector<int> v1 {1, 2, 3, 4, 5};
std::vector<int>::iterator it = v1.begin(); // 指向第一個元素
std::cout << *it << std::endl;
it++; // 指向第二個元素
std::cout << *it << std::endl;
it += 2; // 指向第四個元素
std::cout << *it << std::endl;
it -= 2; // 指向第二個元素
std::cout << *it << std::endl;
it = v1.end() - 1; // 指向最后一個元素,注意end()指向最后一個元素的下一個位置
std::cout << *it << std::endl;
}
void test2()
{
std::cout << "test2 ======================" << std::endl;
std::vector<int> v1 {1, 2, 3, 4, 5};
auto it = v1.begin();
while (it != v1.end())
{
std::cout << *it << std::endl;
it++; // 指向下一個元素
}
it = v1.begin();
while (it != v1.end())
{
*it = 100; // 修改元素值
it++;
}
printVec(v1);
}
void test3()
{
std::cout << "test3 ======================" << std::endl;
std::vector<int> v1 {1, 2, 3, 4, 5};
// std::vector<int>::const_iterator it = v1.begin(); // 常量迭代器,只能讀取元素,不能修改元素
auto it = v1.cbegin(); // 如果使用auto,需要使用cbegin()函數(shù),返回一個常量迭代器
while (it != v1.end())
{
std::cout << *it << std::endl;
it++; // 指向下一個元素
}
it = v1.begin(); // 重新指向第一個元素
while (it != v1.end())
{
// *it = 100; // 報錯,不能修改元素
it++; // 指向下一個元素
}
}
void test4()
{
std::cout << "test4 ======================" << std::endl;
std::vector<int> v1 {1, 2, 3, 4, 5};
auto it = v1.rbegin(); // 返回一個反向迭代器,指向最后一個元素
while (it != v1.rend()) // rend()指向第一個元素的前一個位置
{
std::cout << *it << std::endl;
it++; // 指向下一個元素
}
std::list<std::string> l1 {"hello", "world", "c++"};
auto it2 = l1.rbegin();
std::cout << *it2 << std::endl;
it2++;
std::cout << *it2 << std::endl;
// map 里面的元素會自動按 key 進行排序
std::map<std::string, std::string> m1 {
{"hello", "你好"},
{"world", "世界"},
{"Computer", "計算機"}
};
auto it3 = m1.begin();
while (it3 != m1.end())
{
std::cout << it3->first << " : " << it3->second << std::endl;
it3++;
}
}
int main()
{
// test1();
// test2();
// test3();
test4();
return 0;
}
2、算法
- STL算法基于迭代器生成的序列
- STL提供了很多算法(例如查找、排序、計數(shù)、操作),可以對序列進行操作
- 更多請查看:https://zh.cppreference.com/w/cpp/algorithm
- 多數(shù)算法要求提供額外參數(shù),例如:排序算法需要提供排序規(guī)則,一般使用函數(shù)指針、lambda表達式或仿函數(shù)(函數(shù)對象)
代碼:
/*
* 算法示例
* STL算法基于迭代器生成的序列
* STL提供了很多算法(例如查找、排序、計數(shù)、操作),可以對序列進行操作
* 更多請查看:https://zh.cppreference.com/w/cpp/algorithm
* 多數(shù)算法要求提供額外參數(shù),例如:排序算法需要提供排序規(guī)則,一般使用函數(shù)指針、lambda表達式或仿函數(shù)(函數(shù)對象)
*/
#include <iostream>
#include <vector>
#include <algorithm> // 算法頭文件
#include <list>
void test1()
{
std::cout << "test1 ======================" << std::endl;
std::vector<int> v1{1, 2, 3, 4, 5};
std::vector<int>::iterator loc = std::find(v1.begin(), v1.end(), 3); // 查找3
std::cout << *loc << std::endl; // 3
std::cout << *v1.end() << std::endl; // 0
if (loc != v1.end())
std::cout << "找到 3" << std::endl;
else
std::cout << "未找到 3" << std::endl;
}
void test2()
{
std::cout << "test2 ======================" << std::endl;
std::vector<int> v1{1, 2, 3, 4, 5, 1, 2, 1};
int counts = std::count(v1.begin(), v1.end(), 1); // 統(tǒng)計1的個數(shù)
std::cout << "1的個數(shù): " << counts << std::endl;
}
// 判斷是否是偶數(shù)
bool isEven(int x)
{
return x % 2 == 0;
}
void test3()
{
std::cout << "test3 ======================" << std::endl;
std::vector<int> v1{1, 2, 3, 4, 5, 6, 7, 8, 9};
int counts = std::count_if(v1.begin(), v1.end(), isEven); // 使用函數(shù)指針統(tǒng)計偶數(shù)個數(shù)
counts = std::count_if(v1.begin(), v1.end(), [](int x)
{ return x % 2 == 0; }); // 使用lambda表達式統(tǒng)計偶數(shù)個數(shù)
std::cout << "偶數(shù)個數(shù): " << counts << std::endl;
counts = std::count_if(v1.begin(), v1.end(), [](int x)
{ return x > 6; }); // 統(tǒng)計大于6的個數(shù)
std::cout << "大于6的個數(shù): " << counts << std::endl;
}
void test4()
{
std::cout << "test4 ======================" << std::endl;
std::vector<int> v1{1, 2, 3, 4, 5, 1, 2, 1};
for (const auto &e : v1)
std::cout << e << " ";
std::cout << std::endl;
std::replace(v1.begin(), v1.end(), 1, 100); // 將1替換為100
for (const auto &e : v1)
std::cout << e << " ";
std::cout << std::endl;
}
void test5()
{
std::cout << "test5 ======================" << std::endl;
std::vector<int> v1{1, 2, 3, 4, 5, 6, 7, 8, 9};
if (std::all_of(v1.begin(), v1.end(), [](int x) { return x > 5; }) ) // 所有元素都大于5
std::cout << "所有元素都大于5" << std::endl;
else
std::cout << "不是所有元素都大于5" << std::endl;
if (std::any_of(v1.begin(), v1.end(), [](int x) { return x > 5; }) ) // 至少有一個元素大于5
std::cout << "有元素大于5" << std::endl;
else
std::cout << "沒有元素大于5" << std::endl;
if (std::none_of(v1.begin(), v1.end(), [](int x) { return x < 0; }) ) // 沒有元素小于0
std::cout << "沒有元素小于0" << std::endl;
else
std::cout << "有元素小于0" << std::endl;
}
void test6()
{
std::cout << "test6 ======================" << std::endl;
std::string s1 {"hello world"};
std::cout << s1 << std::endl;
std::transform(s1.begin(), s1.end(), s1.begin(), ::toupper); // 轉(zhuǎn)換為大寫,從s1的begin到end,轉(zhuǎn)換后的結(jié)果放到s1的begin
std::cout << s1 << std::endl;
}
int main()
{
test1();
// test2();
// test3();
// test4();
// test5();
// test6();
return 0;
}
3、array容器示例
- array大小固定,不可改變
- 在內(nèi)存中是連續(xù)的
- 獲取元素的復雜度是常數(shù),與array元素個數(shù)無關(guān)
- 是對原始數(shù)組的封裝,也可以獲取原始數(shù)組的指針
- 如果數(shù)組大小固定,盡量使用array,而不是使用C++原生數(shù)組,因為array可以使用標準庫的算法
代碼:
/*
* array容器示例
* array大小固定,不可改變
* 在內(nèi)存中是連續(xù)的
* 獲取元素的復雜度是常數(shù),與array元素個數(shù)無關(guān)
* 是對原始數(shù)組的封裝,也可以獲取原始數(shù)組的指針
* 如果數(shù)組大小固定,盡量使用array,而不是使用C++原生數(shù)組,因為array可以使用標準庫的算法
*/
#include <iostream>
#include <array> // 使用array容器
#include <algorithm>
#include <numeric>
// 打印數(shù)組
void display(const std::array<int,5> &arr)
{
std::cout << "[ ";
for (const auto &a: arr)
std::cout << a << " ";
std::cout << "]" << std::endl;
}
void test1()
{
std::cout << "test1 ======================" << std::endl;
std::array<int, 5> arr1 {1, 2, 3, 4, 5};
std::array<int, 5> arr2;
display(arr1);
display(arr2); // 未初始化,值為隨機值
arr2 = {10, 20, 30, 40, 50}; // 可以直接賦值
display(arr1);
display(arr2);
std::cout << "arr1的大?。? << arr1.size() << std::endl;
std::cout << "arr2的大?。? << arr2.size() << std::endl;
arr1[0] = 1000;
arr1.at(1) = 2000;
display(arr1);
std::cout << "arr1的第一個元素:" << arr1.front() << std::endl;
std::cout << "arr1的最后一個元素:" << arr1.back() << std::endl;
}
void test2()
{
std::cout << "test2 ======================" << std::endl;
std::array<int, 5> arr1 {1, 2, 3, 4, 5};
std::array<int, 5> arr2 {10, 20, 30, 40, 50};
display(arr1);
display(arr2);
arr1.fill(0);
display(arr1);
display(arr2);
arr1.swap(arr2);
display(arr1);
display(arr2);
}
void test3()
{
std::cout << "test3 ======================" << std::endl;
std::array<int, 5> arr1 {1, 2, 3, 4, 5};
int *ptr = arr1.data(); // 返回數(shù)組的首地址
std::cout << ptr << std::endl;
std::cout << *ptr << std::endl;
*ptr = 1000;
display(arr1);
}
void test4()
{
std::cout << "test4 ======================" << std::endl;
std::array<int, 5> arr1 {3,1,4,2,5};
display(arr1);
std::sort(arr1.begin(), arr1.end());
display(arr1);
}
void test5()
{
std::cout << "test5 ======================" << std::endl;
std::array<int, 5> arr1 {3,6,4,2,5};
std::array<int, 5>::iterator min_val = std::min_element(arr1.begin(), arr1.end());
auto max_val = std::max_element(arr1.begin(), arr1.end());
std::cout << "min: " << *min_val << std::endl;
std::cout << "max: " << *max_val << std::endl;
}
void test6()
{
std::cout << "test6 ======================" << std::endl;
std::array<int, 5> arr1 {3,6,2,2,5};
auto adjacent = std::adjacent_find(arr1.begin(), arr1.end()); // 查找相鄰的兩個相同的元素
if (adjacent != arr1.end())
std::cout << "adjacent: " << *adjacent << std::endl;
else
std::cout << "沒有找到相鄰的兩個相同的元素" << std::endl;
}
void test7()
{
std::cout << "test7 ======================" << std::endl;
std::array<int, 5> arr1 {1,2,3,4,5};
int sum = std::accumulate(arr1.begin(), arr1.end(), 0); // 求和
std::cout << "sum: " << sum << std::endl;
}
void test8()
{
std::cout << "test8 ======================" << std::endl;
std::array<int, 10> arr1 {1,2,3,4,5,5,5,5,5,5};
int counts = std::count(arr1.begin(), arr1.end(), 5); // 統(tǒng)計5的個數(shù)
std::cout << "5一共出現(xiàn)了" << counts << "次" << std::endl;
}
int main()
{
// test1();
// test2();
// test3();
// test4();
// test5();
// test6();
// test7();
test8();
return 0;
}
4、vector示例
- vector是一個動態(tài)數(shù)組,可以隨意增加元素
- 與array一樣,vector在內(nèi)存中是連續(xù)的,對應(yīng)的內(nèi)存空間會隨著元素的增加而增加
- 獲取元素的復雜度是常數(shù),與vector的大小無關(guān)
- 在vector末尾增加、刪除元素的復雜度是常數(shù),與vector的大小無關(guān)
- 在vector中間增加、刪除元素的復雜度是線性的,與vector的大小有關(guān)
- 可以使用迭代器和算法
代碼:
/*
* vector示例
* vector是一個動態(tài)數(shù)組,可以隨意增加元素
* 與array一樣,vector在內(nèi)存中是連續(xù)的,對應(yīng)的內(nèi)存空間會隨著元素的增加而增加
* 獲取元素的復雜度是常數(shù),與vector的大小無關(guān)
* 在vector末尾增加、刪除元素的復雜度是常數(shù),與vector的大小無關(guān)
* 在vector中間增加、刪除元素的復雜度是線性的,與vector的大小有關(guān)
* 可以使用迭代器和算法
*/
#include <iostream>
#include <vector>
#include <algorithm>
// 打印vector的函數(shù)模板
template <typename T>
void printVector(const std::vector<T> &v)
{
std::cout << "[";
for (const auto &e : v)
std::cout << e << " ";
std::cout << "]" << std::endl;
}
void test1()
{
std::cout << "test1 ======================" << std::endl;
std::vector<int> v1{1, 2, 3, 4, 5};
printVector(v1);
v1 = {10, 20, 30, 40, 50}; // 可以直接賦值
printVector(v1);
std::vector<int> v2(10, 88); // 10個88
printVector(v2);
}
void test2()
{
std::cout << "test2 ======================" << std::endl;
std::vector<int> v1{1, 2, 3, 4, 5};
printVector(v1);
std::cout << "size: " << v1.size() << std::endl; // 大小
std::cout << "capacity: " << v1.capacity() << std::endl; // 容量
std::cout << "max_size: " << v1.max_size() << std::endl; // 最大容量
v1.push_back(6); // 在尾部添加元素
printVector(v1);
std::cout << "size: " << v1.size() << std::endl; // 大小
std::cout << "capacity: " << v1.capacity() << std::endl; // 容量,每超出一次,容量翻倍
std::cout << "max_size: " << v1.max_size() << std::endl; // 最大容量
v1.shrink_to_fit(); // 釋放多余的內(nèi)存
printVector(v1);
std::cout << "size: " << v1.size() << std::endl; // 大小
std::cout << "capacity: " << v1.capacity() << std::endl; // 容量,釋放多余的內(nèi)存后,容量恢復到size大小
std::cout << "max_size: " << v1.max_size() << std::endl; // 最大容量
v1.reserve(100); // 預(yù)留100個元素的空間
printVector(v1);
std::cout << "size: " << v1.size() << std::endl; // 大小
std::cout << "capacity: " << v1.capacity() << std::endl; // 容量,預(yù)留100個元素的空間后,容量恢復到100,直到超出100
std::cout << "max_size: " << v1.max_size() << std::endl; // 最大容量
}
void test3()
{
std::cout << "test3 ======================" << std::endl;
std::vector<int> v1{1, 2, 3, 4, 5};
printVector(v1);
v1[0] = 100;
v1.at(1) = 200;
printVector(v1);
std::cout << "v1的第一個元素: " << v1.front() << std::endl;
std::cout << "v1的最后一個元素: " << v1.back() << std::endl;
v1.pop_back(); // 刪除最后一個元素
printVector(v1);
}
void test4()
{
std::vector<int> v1{1, 2, 3, 4, 5};
printVector(v1);
v1.clear(); // 清空容器
printVector(v1);
v1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
printVector(v1);
v1.erase(v1.begin(), v1.begin() + 3); // 刪除前三個元素
printVector(v1);
// 刪除所有偶數(shù)
v1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::vector<int>::iterator it = v1.begin(); // 獲取迭代器
while (it != v1.end())
{
if (*it % 2 == 0)
v1.erase(it);
else
it++;
}
printVector(v1);
}
void test5()
{
std::cout << "test5 ======================" << std::endl;
// 交換兩個vector
std::vector<int> v1{1, 2, 3, 4, 5};
std::vector<int> v2{10, 20, 30, 40, 50};
printVector(v1);
printVector(v2);
v1.swap(v2);
printVector(v1);
printVector(v2);
}
void test6()
{
std::cout << "test6 ======================" << std::endl;
std::vector<int> v1{9, 2, 5, 4, 7, 6, 8, 1, 3};
printVector(v1);
std::sort(v1.begin(), v1.end()); // 排序
printVector(v1);
}
// 判斷是否為偶數(shù)
int getEven(int x)
{
return x % 2 == 0;
}
void test7()
{
std::cout << "test7 ======================" << std::endl;
std::vector<int> v1{1, 2, 3, 4, 5};
std::vector<int> v2{10, 20};
printVector(v1);
printVector(v2);
std::copy(v1.begin(), v1.end(), std::back_inserter(v2)); // 拷貝
printVector(v1);
printVector(v2);
v1 = {1, 2, 3, 4, 5};
v2 = {10, 20};
// std::copy_if(v1.begin(),v1.end(),std::back_inserter(v2),getEven); // 拷貝偶數(shù)
std::copy_if(v1.begin(), v1.end(), std::back_inserter(v2), [](int x)
{ return x % 2 == 0; }); // 使用lambda表達式
printVector(v1);
printVector(v2);
}
void test8()
{
std::cout << "test8 ======================" << std::endl;
std::vector<int> v1{1, 2, 3, 4, 5};
std::vector<int> v2{10, 20, 30, 40, 50};
std::vector<int> v3;
std::transform(v1.begin(), v1.end(), v2.begin(), std::back_inserter(v3),
[](int x, int y)
{ return x + y; }); // 加法
// std::transform(v1.begin(), v1.end(), v2.begin(), std::back_inserter(v3), std::plus<int>()); // 使用內(nèi)置的加法函數(shù)
std::cout << "v1 + v2 = " << std::endl;
printVector(v3);
v3.clear(); // 清空容器
std::transform(v1.begin(), v1.end(), v2.begin(), std::back_inserter(v3),
[](int x, int y)
{ return x * y; }); // 乘法
// std::transform(v1.begin(), v1.end(), v2.begin(), std::back_inserter(v3), std::multiplies<int>()); // 使用內(nèi)置的乘法函數(shù)
std::cout << "v1 * v2 = " << std::endl;
printVector(v3);
}
void test9()
{
std::cout << "test9 ======================" << std::endl;
std::vector<int> v1{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::vector<int> v2{100, 200, 300, 400};
printVector(v1);
printVector(v2);
auto it = std::find(v1.begin(), v1.end(), 5); // 查找5第一次出現(xiàn)的位置
if (it != v1.end())
{
std::cout << "找到了:5 " << std::endl;
v1.insert(it, v2.begin(), v2.end()); // 插入
}
else
{
std::cout << "沒有找到" << std::endl;
}
printVector(v1);
}
int main()
{
// test1();
// test2();
// test3();
// test4();
// test5();
// test6();
// test7();
// test8();
test9();
return 0;
}
5、deque(double ended queue,雙端數(shù)組)示例
- 動態(tài)數(shù)組,和vector類似,但是deque是雙端的,可以在頭部和尾部進行插入和刪除操作
- 與vector不同,deque在內(nèi)存中是分段連續(xù)的,每段內(nèi)存都是連續(xù)的,所以在頭部和尾部插入和刪除元素都很快
- 獲取元素的復雜度是常數(shù)
- 在頭部和尾部插入和刪除元素的復雜度是常數(shù)
- 在中間插入和刪除元素的復雜度是線性的
- 支持迭代器和算法
代碼:
/*
* deque(double ended queue,雙端數(shù)組)示例
* 動態(tài)數(shù)組,和vector類似,但是deque是雙端的,可以在頭部和尾部進行插入和刪除操作
* 與vector不同,deque在內(nèi)存中是分段連續(xù)的,每段內(nèi)存都是連續(xù)的,所以在頭部和尾部插入和刪除元素都很快
* 獲取元素的復雜度是常數(shù)
* 在頭部和尾部插入和刪除元素的復雜度是常數(shù)
* 在中間插入和刪除元素的復雜度是線性的
* 支持迭代器和算法
*/
#include <iostream>
#include <deque>
#include <vector>
#include <algorithm>
// 用于顯示deque的函數(shù)模板
template <typename T>
void display(const std::deque<T> &d)
{
std::cout << "[ ";
for (const auto &item:d )
std::cout << item << " ";
std::cout << "]";
std::cout << std::endl;
}
void test1()
{
std::cout << "test1 ======================" << std::endl;
std::deque<int> d1{1, 2, 3, 4, 5};
display(d1);
std::deque<int> d2 (10,100);
display(d2);
d2[0] = 99;
d2.at(1) = 88;
display(d2);
}
void test2()
{
std::cout << "test2 ======================" << std::endl;
std::deque<int> d1 {0,0,0,0};
display(d1);
d1.push_back(10);
d1.push_back(20);
display(d1);
d1.push_front(100);
d1.push_front(200);
display(d1);
std::cout << "第一個元素: " << d1.front() << std::endl;
std::cout << "最后一個元素: " << d1.back() << std::endl;
std::cout << "大小: " << d1.size() << std::endl;
d1.pop_back();
d1.pop_front();
display(d1);
}
void test3()
{
std::cout << "test3 ======================" << std::endl;
std::vector<int> v1 {1,2,3,4,5,6,7,8,9,10};
std::deque<int> d2;
// 將vector中的偶數(shù)放入deque后,奇數(shù)放入deque前
for (const auto &item:v1)
{
if (item % 2 == 0)
d2.push_back(item);
else
d2.push_front(item);
}
display(d2);
}
void test4()
{
std::cout << "test4 ======================" << std::endl;
std::vector<int> v1 {1,2,3,4,5,6,7,8,9,10};
std::deque<int> d2;
// 將vector中的元素放到d2后
for (const auto &item:v1)
d2.push_back(item);
display(d2);
d2.clear(); // 清空deque
// 將vector中的元素放到d2前
for (const auto &item:v1)
d2.push_front(item);
display(d2);
}
void test5()
{
std::cout << "test5 ======================" << std::endl;
std::vector<int> v1 {1,2,3,4,5,6,7,8,9,10};
std::deque<int> d2;
// 使用std::copy實現(xiàn)test4效果
std::copy(v1.begin(), v1.end(), std::back_inserter(d2));
display(d2);
d2.clear(); // 清空deque
std::copy(v1.begin(), v1.end(), std::front_inserter(d2));
display(d2);
}
int main()
{
// test1();
// test2();
// test3();
// test4();
test5();
return 0;
}
6、list(鏈表)容器
- 動態(tài)大小
- list是一個雙向鏈表,支持快速的插入和刪除操作
- list不支持隨機訪問,不支持下標運算符
代碼:
/*
* list(鏈表)容器
* 動態(tài)大小
* list是一個雙向鏈表,支持快速的插入和刪除操作
* list不支持隨機訪問,不支持下標運算符
*/
#include <iostream>
#include <list>
#include <algorithm>
// 打印list的函數(shù)模板
template <typename T>
void printList(const std::list<T> &l)
{
std::cout << "[";
for (const auto &e : l)
std::cout << e << " ";
std::cout << "]" << std::endl;
}
void test1()
{
std::cout << "test1 ======================" << std::endl;
std::list<int> l1 {1, 2, 3, 4, 5};
printList(l1);
std::list<std::string> l2;
l2.push_back("hello");
l2.push_back("world");
printList(l2);
std::list<int> l3;
l3 = {1,2,3,4,5,6,7,8,9,10};
printList(l3);
std::list<int> l4 (10,88);
printList(l4);
}
void test2()
{
std::cout << "test2 ======================" << std::endl;
std::list<int> l1 {1,2,3,4,5,6,7,8,9,10};
printList(l1);
std::cout << "第一個元素: " << l1.front() << std::endl;
std::cout << "最后一個元素: " << l1.back() << std::endl;
std::cout << "大小: " << l1.size() << std::endl;
l1.clear();
printList(l1);
std::cout << "大小: " << l1.size() << std::endl;
}
void test3()
{
std::cout << "test3 ======================" << std::endl;
std::list<int> l1 {1,2,3,4,5,6,7,8,9,10};
printList(l1);
l1.resize(5); // 縮小到5個元素
printList(l1);
}
void test4()
{
std::cout << "test4 ======================" << std::endl;
std::list<int> l1 {1,2,3,4,5,6,7,8,9,10};
printList(l1);
// 找到第一個5,然后在5前面追加一個100
std::list<int>::iterator it = std::find(l1.begin(), l1.end(), 5);
if (it != l1.end())
l1.insert(it, 100);
printList(l1);
std::list<int> l2 {1000, 2000, 3000};
// 將l2中的元素插入到l1中
l1.insert(it, l2.begin(), l2.end());
printList(l1);
std::advance(it, -2); // it向前移動2個位置
std::cout << *it << std::endl;
l1.erase(it); // 刪除it指向的元素,也就是2000
printList(l1);
}
void test5()
{
std::cout << "test5 ======================" << std::endl;
std::list<int> l1 {3,5,2,10,7,9,8,1,4,6};
printList(l1);
l1.sort();
printList(l1);
}
int main()
{
// test1();
// test2();
// test3();
// test4();
test5();
return 0;
}
7、set示例
- set是一種關(guān)聯(lián)式容器
- 根據(jù)元素的值,自動排序,重復元素會被自動去重
- 不支持隨機訪問,不支持下標運算符
- 支持各種迭代器和算法
代碼:
/*
* set示例
* set是一種關(guān)聯(lián)式容器
* 根據(jù)元素的值,自動排序,重復元素會被自動去重
* 不支持隨機訪問,不支持下標運算符
* 支持各種迭代器和算法
*/
#include <iostream>
#include <set>
// 用于顯示set的函數(shù)模板
template <typename T>
void printSet(const std::set<T> &s)
{
std::cout << "[";
for (const auto &e : s)
std::cout << e << " ";
std::cout << "]" << std::endl;
}
void test1()
{
std::cout << "test1 ======================" << std::endl;
std::set<int> s1{1, 2, 3, 4, 5};
printSet(s1);
s1 = {1,1,1,2,2,2,3,3,3}; // 重復元素會被自動去重
printSet(s1);
s1.insert(10);
s1.insert(0);
printSet(s1);
if (s1.count(10)) // count返回1表示找到,返回0表示未找到
std::cout << "找到10" << std::endl;
else
std::cout << "未找到10" << std::endl;
auto it = s1.find(10); // find返回迭代器,如果找到,返回迭代器指向該元素,否則返回end()
if (it != s1.end())
std::cout << "找到" << *it << std::endl;
s1.clear();
printSet(s1);
}
void test2()
{
std::cout << "test2 ======================" << std::endl;
std::set<std::string> s1 {"A", "B", "C", "D", "E"};
printSet(s1);
auto result = s1.insert("F"); // insert返回一個pair,第一個元素是迭代器,指向插入的元素,第二個元素是bool,表示是否插入成功
printSet(s1);
std::cout << std::boolalpha; // boolalpha表示輸出true/false
std::cout << "first: " << *(result.first) << std::endl;
std::cout << "second: " << result.second << std::endl; // 插入成功,返回true
result = s1.insert("A"); // A 已經(jīng)存在,插入失敗,但是返回的迭代器指向A
printSet(s1);
std::cout << std::boolalpha; // boolalpha表示輸出true/false
std::cout << "first: " << *(result.first) << std::endl;
std::cout << "second: " << result.second << std::endl; // 插入失敗,返回false,表示有重復元素
}
int main()
{
// test1();
test2();
return 0;
}
8、map示例
- map是一種關(guān)聯(lián)式容器,它的元素是key-value對(std::pair),key是唯一的,value可以重復
- map中的元素是按key自動排序的
- 使用key訪問元素
代碼:
/*
* map示例
* map是一種關(guān)聯(lián)式容器,它的元素是key-value對(std::pair),key是唯一的,value可以重復
* map中的元素是按key自動排序的
* 使用key訪問元素
*/
#include <iostream>
#include <map>
#include <set>
// 打印map的函數(shù)模板
template <typename T1, typename T2>
void printMap(const std::map<T1, T2> &m)
{
std::cout << "[";
for (const auto &e : m)
std::cout << e.first << ":" << e.second << " ";
std::cout << "]" << std::endl;
}
// map的value是set
void printMap(const std::map<std::string, std::set<int>> &m)
{
std::cout << "[";
for (const auto &e : m)
{
std::cout << e.first << ":[ ";
for (const auto &s : e.second)
std::cout << s << " ";
std::cout << "] ";
}
std::cout << "]" << std::endl;
}
void test1()
{
std::cout << "test1 ======================" << std::endl;
std::map<std::string, int> m1 { // string是key,int是value
{"mike", 10},
{"jane", 20},
{"tom", 30},
};
printMap(m1); // [jane:20 mike:10 tom:30 ],會自動按key排序
m1.insert(std::pair<std::string, int>("anna", 100)); // 插入一個pair
printMap(m1);
m1.insert(std::make_pair("bob", 200)); // 插入一個pair
printMap(m1);
m1["jim"] = 300; // 如果key不存在,會自動插入一個pair,如果key存在,會更新value
printMap(m1);
m1["jim"] += 100; // 更新value
printMap(m1);
std::cout << "mike的計次:" << m1.count("mike") << std::endl; // count返回1表示找到,返回0表示未找到
std::cout << "alice的計次:" << m1.count("alice") << std::endl;
auto it = m1.find("jim"); // find返回迭代器,如果未找到,返回end()
if (it != m1.end())
std::cout << "找到" << it->first << ",value為" << it->second << std::endl;
else
std::cout << "未找到j(luò)im" << std::endl;
m1.clear(); // 清空map
printMap(m1);
}
void test2()
{
std::cout << "test2 ======================" << std::endl;
std::map<std::string, std::set<int>> student_grades { // string是key,set是value
{"mike", {100, 90}},
{"jane", {99, 88, 77}},
{"tom", {98, 87, 76}},
};
printMap(student_grades);
student_grades["mike"].insert(80); // 插入80分
printMap(student_grades);
auto it = student_grades.find("jane");
if (it != student_grades.end())
{
it->second.erase(88); // 刪除88分
printMap(student_grades);
}
}
int main()
{
// test1();
test2();
return 0;
}
9、stack 示例
- stack 是一種容器適配器,遵循后進先出(LIFO)的原則
- stack 本身不是容器,它是基于容器實現(xiàn)的(如vector、list、deque等)
- 所有的操作都在棧頂進行(top)
- stack 本身沒有迭代器
代碼:
/*
* stack 示例
* stack 是一種容器適配器,遵循后進先出(LIFO)的原則
* stack 本身不是容器,它是基于容器實現(xiàn)的(如vector、list、deque等)
* 所有的操作都在棧頂進行(top)
* stack 本身沒有迭代器
*/
#include <iostream>
#include <stack>
#include <vector>
#include <list>
#include <deque>
// 顯示stack的函數(shù)模板
template <typename T>
void display(std::stack<T> s)
{
std::cout << "[";
while (!s.empty())
{
T elem = s.top(); // 讀取棧頂元素
std::cout << elem << " ";
s.pop(); // 彈出棧頂元素
}
std::cout << "]" << std::endl;
}
int main()
{
std::stack<int> s;
for (auto i: {1,2,3,4,5})
s.push(i);
display(s);
s.push(100); // 壓入元素
display(s);
s.pop(); // 彈出元素
s.pop();
display(s);
// s.clear(); // 并沒有clear()方法
while (!s.empty())
s.pop(); // 彈出所有元素
display(s);
s.push(10);
display(s);
s.top() = 100; // 修改棧頂元素
display(s);
return 0;
}
10、queue示例
- queue是一種容器適配器,遵循先進先出(FIFO)的原則
- queue的底層容器可以是deque、list
- 元素只能從隊尾壓入,從隊首彈出(排隊)
- queue本身沒有提供迭代器
代碼:文章來源:http://www.zghlxwxcb.cn/news/detail-740977.html
/*
* queue示例
* queue是一種容器適配器,遵循先進先出(FIFO)的原則
* queue的底層容器可以是deque、list
* 元素只能從隊尾壓入,從隊首彈出(排隊)
* queue本身沒有提供迭代器
*/
#include <iostream>
#include <queue>
// 顯示queue的函數(shù)模板
template <typename T>
void display(std::queue<T> q)
{
std::cout << "[";
while (!q.empty())
{
T elem = q.front(); // 讀取隊首元素
std::cout << elem << " ";
q.pop(); // 彈出隊首元素
}
std::cout << "]" << std::endl;
}
int main()
{
std::queue<int> q;
for (auto i : {1, 2, 3, 4, 5})
q.push(i);
display(q);
std::cout << "隊首元素: " << q.front() << std::endl;
std::cout << "隊尾元素: " << q.back() << std::endl;
q.push(100); // 壓入元素
display(q);
q.pop(); // 彈出元素
q.pop();
display(q);
// q.clear(); // 并沒有clear()方法
while (!q.empty())
q.pop(); // 彈出所有元素
display(q);
std::cout << "size: " << q.size() << std::endl;
q.push(10);
q.push(20);
q.push(30);
display(q);
std::cout << "第一個元素: " << q.front() << std::endl;
std::cout << "最后一個元素: " << q.back() << std::endl;
q.front() = 100; // 修改隊首元素
q.back() = 200; // 修改隊尾元素
display(q);
return 0;
}
11、priority_queue (優(yōu)先級隊列)示例
- 允許按照優(yōu)先級來插入和刪除元素
- 優(yōu)先級最高的元素總是位于隊首(最大值在隊首)
- 本身沒有提供迭代器
代碼:文章來源地址http://www.zghlxwxcb.cn/news/detail-740977.html
/*
* priority_queue (優(yōu)先級隊列)示例
* 允許按照優(yōu)先級來插入和刪除元素
* 優(yōu)先級最高的元素總是位于隊首(最大值在隊首)
* 本身沒有提供迭代器
*/
#include <iostream>
#include <queue>
// 顯示priority_queue的函數(shù)模板
template <typename T>
void display(std::priority_queue<T> pq)
{
std::cout << "[";
while (!pq.empty())
{
T elem = pq.top(); // 讀取優(yōu)先級最高元素
std::cout << elem << " ";
pq.pop(); // 彈出優(yōu)先級最高元素
}
std::cout << "]" << std::endl;
}
void test1()
{
std::cout << "test1 ======================" << std::endl;
std::priority_queue<int> pq;
for (auto i : {3,5,8,1,2,9,4,7,6})
pq.push(i);
display(pq);
std::cout << "大小: " << pq.size() << std::endl;
std::cout << "最大值: " << pq.top() << std::endl;
pq.pop(); // 彈出最大值
display(pq);
}
int main()
{
test1();
return 0;
}
到了這里,關(guān)于C++進階語法——STL 標準模板庫(下)(Standard Template Library)【學習筆記(七)】的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!