概述:
算法主要由頭文件<algorithm> <functional> <numeric> 提供
<algorithm> 是所有 STL 頭文件中最大的一個,提供了超過 90 個支持各種各樣算法的函數,包括排序、合并、搜索、去重、分解、遍歷、數值交換、拷貝和替換、插入和刪除等
<functional> 定義了一些模板類,用以聲明函數對象。函數對象(function object)是一個重載了函數調用操作符(operator())的類。
<numeric> 定義了執行算術運算的一些模板函數。
1. 常用遍歷算法
學習目標:
掌握常用的遍歷算法
算法簡介:
for_each // 遍歷容器
transform // 搬運容器到另一個容器中
1.1 for_each
函數原型
for_each(iterator beg, iterator end, _func)
beg 起始迭代器
end 結束迭代器
_func 函數或者函數對象
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <functional>
using namespace std;#define CEHUA 0
#define MEISHU 1
#define YANFA 2// 普通函數
void print01(int val){cout << val << " ";
}// 防函數
class PrintData{
public:void operator()(int val){cout << val << " ";}
};void test01()
{// 邏輯非vector<int> v;for(int i = 0; i < 10; i++){v.push_back(i);}for_each(v.begin(), v.end(), print01);cout << endl;// 防函數for_each(v.begin(), v.end(), PrintData());cout << endl;// Lambda 表達式for_each(v.begin(), v.end(), [](int val){cout << val << " ";});cout << endl;
}int main(int argc, char const *argv[])
{test01();return 0;
}
1.2 transform
概念:
搬運容器到另一個容器中
函數原型:
transform(iterator beg1, iterator end1, iteartor beg2, _fuc);
beg1 原容器開始迭代器
end1 原容器結束迭代器
beg2 目標起始迭代器
_fuc 函數或者函數對象
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <functional>
using namespace std;#define CEHUA 0
#define MEISHU 1
#define YANFA 2// stL 常用算法 transform// transform(iterator beg1, iterator end1, iteartor beg2, _fuc); class Transform{
public:int operator()(int val){// 將數字翻倍return val * 2;}};void test01()
{vector<int> v;for (int i = 0; i < 10; i++){v.push_back(i);}vector<int> v2;v2.resize(v.size()); // 目標容器需要提前開辟空間transform(v.begin(), v.end(), v2.begin(),Transform());// 遍歷容器for_each(v2.begin(), v2.end(), [](int val){cout << val << " ";});
}int main(int argc, char const *argv[])
{test01();return 0;
}
2. 常用查找算法
算法簡介
find // 查找元素
find_if // 按條件查找元素
adjacent_find // 查找相鄰重復元素
binary_search // 二分查找
count // 統計元素個數
count_if // 按條件統計元素個數
2.1 find
查找指定元素,找到返回指定元素的迭代器,找不到返回end()
函數原型
find(begin, end, val)
begin 開始迭代器
end 結束迭代器
val 查找的元素
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <functional>
using namespace std;#define CEHUA 0
#define MEISHU 1
#define YANFA 2// stL 常用查找算法// find // 查找內置的數據類型
void test01()
{vector<int> v;for (int i = 0; i < 10; i++){v.push_back(i);}// 查找容器中是否有6vector<int>::iterator it = find(v.begin(), v.end(), 6);if(it == v.end()){cout << "沒有找到" << endl;}else{cout << "找到元素為:" << *it << endl;}}// 查找自定義數據類型
class Person{
public:Person(string name, int age):m_Name(name),m_Age(age){}string m_Name;int m_Age;// 重載==bool operator==(const Person &p){if(this->m_Name == p.m_Name && this->m_Age == p.m_Age){return true;}else{return false;}}
};void test02(){vector<Person> v;Person p1("西施", 18);Person p2("王昭君", 19);Person p3("楊玉環", 17);Person p4("貂蟬", 16);Person p5("小喬", 15);v.push_back(p1);v.push_back(p2);v.push_back(p3);v.push_back(p4);v.push_back(p5);Person p("貂蟬", 16);vector<Person>::iterator it = find(v.begin(), v.end(), p);if(it == v.end()){cout << "沒有找到" << endl;}else{cout << "找到元素為:" << it->m_Name << " " << it->m_Age << endl;}
}int main(int argc, char const *argv[])
{test02();return 0;
}
查找自定義數據,必須重載==
2.2 find_if
功能描述:
按條件查找元素
函數原型
find_if(iterator beg, iterator end, _Pred)
功能描述:按條件查找元素,找到返回指定位置迭代器,找不到返回結束迭代器位置
注意:_Pred為謂詞(返回bool類型的防函數) 或 函數
beg 開始迭代器
end 結束迭代器
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <functional>
using namespace std;#define CEHUA 0
#define MEISHU 1
#define YANFA 2// stL 常用查找算法// find_if// 查找內置的數據類型
void test01()
{vector<int> v;for (int i = 0; i < 10; i++){v.push_back(i);}// 用lambda表達式實現 查找容器中是有大于6 vector<int>::iterator it = find_if(v.begin(), v.end(), [&](int val){return val > 6;});if(it == v.end()){cout << "沒有找到" << endl;}else{cout << "找到元素為:" << *it << endl;}}// 查找自定義數據類型
class Person{
public:Person(string name, int age):m_Name(name),m_Age(age){}string m_Name;int m_Age;bool operator==(const Person &p){if(this->m_Name == p.m_Name && this->m_Age == p.m_Age){return true;}else{return false;}}
};class findPerson{
public:bool operator()(const Person &p){// 查找年齡大于17的if (p.m_Age > 17){return true;}else{return false;}}
};void test02(){vector<Person> v;Person p1("西施", 18);Person p2("王昭君", 19);Person p3("楊玉環", 17);Person p4("貂蟬", 16);Person p5("小喬", 15);v.push_back(p1);v.push_back(p2);v.push_back(p3);v.push_back(p4);v.push_back(p5);Person p("貂蟬", 16);vector<Person>::iterator it = find_if(v.begin(), v.end(), findPerson());if(it == v.end()){cout << "沒有找到" << endl;}else{cout << "找到元素為:" << it->m_Name << " " << it->m_Age << endl;}
}int main(int argc, char const *argv[])
{test02();return 0;
}
2.3 adjacent_find
功能描述:
查找相鄰重復元素
函數原型:
adjacent_find(iterator first, iterator last, binary_predicate pred);
功能描述:
查找相鄰重復元素,返回相鄰元素的第一個位置的迭代器
參數說明:
first:開始迭代器
last:結束迭代器
pred:二元謂詞
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <functional>
using namespace std;#define CEHUA 0
#define MEISHU 1
#define YANFA 2// stL 常用查找算法// adjacent_find// 查找內置的數據類型
void test01()
{vector<int> v;v.push_back(10);v.push_back(20);v.push_back(20);v.push_back(30);v.push_back(40);v.push_back(30);v.push_back(50);vector<int>::iterator it = adjacent_find(v.begin(), v.end());if (it == v.end()){cout << "找不到" << endl;}else{cout << "找到相鄰重復元素為:" << *it << endl;}}// 查找自定義數據類型
class Person{
public:Person(string name, int age):m_Name(name),m_Age(age){}string m_Name;int m_Age;bool operator==(const Person &p){if(this->m_Name == p.m_Name && this->m_Age == p.m_Age){return true;}else{return false;}}
};class findPerson{
public:bool operator()(const Person &p , const Person &p2){// 查找年齡相同的if (p.m_Age == p2.m_Age){return true;}else{return false;}}
};// 查找自定義數據類型
void test02(){vector<Person> v;Person p1("西施", 18);Person p2("王昭君", 19);Person p3("楊玉環", 19);Person p4("貂蟬", 16);Person p5("小喬", 15);v.push_back(p1);v.push_back(p2);v.push_back(p3);v.push_back(p4);v.push_back(p5);vector<Person>::iterator it = adjacent_find(v.begin(), v.end(), findPerson());if(it == v.end()){cout << "沒有找到" << endl;}else{cout << "找到元素為:" << it->m_Name << " " << it->m_Age << endl;}
}int main(int argc, char const *argv[])
{test02();return 0;
}
2.4 binary_search
查找指定元素是否存在
函數原型
bool binary_search(InputIterator first, InputIterator last, const T& val);
功能描述:
查找到val在[first, last)區間中,則返回true,否則返回false。
注意:在無序序列中不可用。
beg 開始迭代器
end 結束迭代器
val 查找的元素
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <functional>
using namespace std;#define CEHUA 0
#define MEISHU 1
#define YANFA 2// binary_searchvoid test01()
{vector<int> v;for(int i = 0; i < 10; i++){v.push_back(i);}bool result = binary_search(v.begin(), v.end(), 10);if (result){cout << "find" << endl;}else{cout << "not find" << endl;}}int main(int argc, char const *argv[])
{test01();return 0;
}
2.5 count
功能描述:
統計元素個數
函數原型
count(InputIterator first, InputIterator last, const T& val);
功能描述:
統計出元素次數
beg 開始迭代器
end 結束迭代器
val 查找的元素
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <functional>
using namespace std;#define CEHUA 0
#define MEISHU 1
#define YANFA 2// count// 統計內置數據類型
void test01()
{vector<int> v;for(int i = 0; i < 10; i++){v.push_back(i);}v.push_back(10);v.push_back(10);int result = count(v.begin(), v.end(), 10);cout << result << endl;}// 統計自定義數據類型
class Person{
public:Person(string name, int age):m_Name(name), m_Age(age){}bool operator==(const Person &p){if(this->m_Age == p.m_Age){return true;}else{return false;}}string m_Name;int m_Age;
};void test02(){vector<Person> v;v.push_back(Person("西施", 18));v.push_back(Person("小龍女", 18));v.push_back(Person("貂蟬", 20));v.push_back(Person("楊玉環", 18));v.push_back(Person("王昭君", 19));Person p("小喬",18);int result = count(v.begin(), v.end(), p);cout << "和小喬年齡相同的人有" << result << "個";
}int main(int argc, char const *argv[])
{test02();return 0;
}
總結:統計自定義類型的時候,需要重載 operator==
2.6 count_if
功能描述: 按照條件在容器中統計元素個數
函數原型:
count_if(iterator beg, iterator end, _Pred)
beg 開始迭代器
end 結束迭代器
_Pred 謂詞
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <functional>
#include <algorithm>
using namespace std;#define CEHUA 0
#define MEISHU 1
#define YANFA 2// count_ifclass Greater{
public:Greater(int val):m_Val(val){}bool operator()(int val){return val > m_Val;}int m_Val; // 可以改變條件
};// 統計內置數據類型
void test01()
{vector<int> v;for(int i = 0; i < 10; i++){v.push_back(i);}v.push_back(10);v.push_back(10);// 統計大于8的數字有多少個int result = count_if(v.begin(), v.end(), Greater(8));cout << result << endl;
}// 統計自定義數據類型
class Person{
public:Person(string name, int age):m_Name(name), m_Age(age){}bool operator==(const Person &p){if(this->m_Age == p.m_Age){return true;}else{return false;}}string m_Name;int m_Age;
};class CountPerson{
public:CountPerson(int age):m_Age(age){}bool operator()(const Person &p){return p.m_Age > m_Age;}int m_Age;
};void test02(){vector<Person> v;v.push_back(Person("西施", 18));v.push_back(Person("小龍女", 18));v.push_back(Person("貂蟬", 20));v.push_back(Person("楊玉環", 18));v.push_back(Person("王昭君", 19));Person p("小喬",18);v.push_back(p);int result = count_if(v.begin(), v.end(), CountPerson(17));cout << "年齡大于17的美女: " << result << "個";
}int main(int argc, char const *argv[])
{test02();return 0;
}