文章目錄
C++編程提高——STL函數對象和常用算法
一、函數對象
1.1函數對象概念
概念:
- 重載函數調用操作符的類,其對象常稱爲函數對象
- 函數對象使用重載的()時,行爲類似函數調用,也叫仿函數
本質:
- 函數對象(仿函數)是一個類,不是一個函數
1.2函數對象的使用
特點:
- 函數對象在使用時,可以向普通函數那樣調用,可以有參數,可以有返回值
- 函數對象超出普通函數的概念,函數對象可以有自己的狀態
- 函數對象可以作爲參數傳遞
示例:
#include<iostream>
using namespace std;
//函數對象創建
class MyAdd {
public:
int operator()(int a, int b) {
return a + b;
}
};
void test81() {
MyAdd ma;
cout << "1----" << ma(13, 24) << endl;
}
//函數對象有自己的狀態
class MyPrint {
public:
MyPrint() {
this->count = 0;
}
void operator()(string msg) {
cout << msg << endl;
this->count++;
}
int count;
};
void test82() {
MyPrint mp;
mp("hello world");
mp("hello world");
mp("hello world");
mp("hello world");
mp("hello world");
cout << "count = " << mp.count << endl;
}
//函數對象作爲參數傳遞
void doPrint(MyPrint& p, string msg) {
p(msg);
}
void test83() {
MyPrint mp;
doPrint(mp, "Hello World");
}
int main() {
test83();
system("pause");
return 0;
}
1.3謂詞
1.3.1謂詞概念
概念:
- 返回
bool
類型的仿函數稱爲謂詞 - 如果一個仿函數接受一個參數,那麼就叫做一元謂詞
- 如果一個仿函數接收兩個參數,那麼就叫做二元謂詞
1.3.2一元謂詞
//一元謂詞
class Getnum {
public:
bool operator()(int a) {
return a > 5;
}
};
void test91() {
vector<int> v;
v.push_back(10);
v.push_back(3);
v.push_back(4);
v.push_back(6);
vector<int>::iterator it = find_if(v.begin(), v.end(), Getnum());
cout << *it << endl;
it++;
cout << *it << endl;
}
1.3.3二元謂詞
//二元謂詞
class MyCom {
public:
bool operator()(int v1, int v2) {
return v1 > v2;
}
};
void test92() {
vector<int> v;
v.push_back(10);
v.push_back(3);
v.push_back(4);
v.push_back(6);
sort(v.begin(), v.end());
for (vector<int>::iterator it = v.begin(); it != v.end(); it ++) {
cout << *it << endl;
}
sort(v.begin(), v.end(), MyCom());
cout << "排序後" << endl;
for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
cout << *it << endl;
}
}
1.4內建函數對象
1.4.1內建函數對象意義
概念:
- STL內建了一些函數對象
分類:
- 算數仿函數
- 關係仿函數
- 邏輯仿函數
用法:
- 這些仿函數所產生的對象,用法和一般函數完全相同
- 使用內建函數對象,需要引入頭文件
#include<functional>
1.4.2算數仿函數
功能描述:
- 實現四則運算
- 其中negate是一元運算,其他都是二元運算
仿函數原型:
函數 | 描述 |
---|---|
template<class T> T plus<T> |
加法 |
template<class T> T minus<T> |
減法 |
template<class T> T multiplies<T> |
乘法 |
template<class T> T divides<T> |
除法 |
template<class T> T modulus<T> |
取模 |
template<class T> T negate<T> |
取餘 |
1.4.3關係仿函數
仿函數原型:
函數 | 描述 |
---|---|
template<class T> bool equal_to<T> |
等於 |
template<class T> bool not_equal<T> |
不等於 |
template<class T> bool greater<T> |
大於 |
template<class T> bool greater_equal<T> |
大於等於 |
template<class T> bool less<T> |
小於 |
template<class T> bool less_equal<T> |
小於等於 |
1.4.4邏輯仿函數
仿函數原型:
函數 | 描述 |
---|---|
template<class T> bool logical_and<T> |
與 |
template<class T> bool logical_or<T> |
或 |
template<class T> bool logical_not<T> |
非 |
二、常用算法
概述:
- 算法主要是有頭文件
<algorithm>
<functional>
<numeric>
組成 <algorithm>
是所有STL頭文件中最大的一個,範圍涉及到比較、交換、查找、遍歷操作、複製、修改等等<numeric>
體積很小,只包括幾個在序列上面進行簡單數學運算的模板函數<functional>
定義了一些模板類,用於聲明函數對象
2.1常用遍歷算法
簡介:
for_each
:遍歷容器transform
:搬運容器到另一個容器中
2.1.1for_each
函數原型:
for_each(iterator beg, iterator end, _func);
beg
:開始迭代器end
:結束迭代器_func
:函數或者函數對象
2.1.2transform
函數原型:
transform(iterator beg1, iterator end1, iterator beg2, _func);
beg1
:源容器開始迭代器end1
:原容器結束迭代器beg2
:目標容器開始迭代器_func
:函數或者函數對象
2.2常用查找算法
算法簡介:
find
:查找元素find_if
:按條件查找元素adjacent_find
:查找相鄰重複元素binary_search
:二分查找法count
:統計元素個數count_if
:按條件統計元素個數
2.2.1find
函數原型:
find(iterator beg, iterator end, value);
:按值查找元素,找不到返回結束迭代器位置beg
:開始迭代器end
:結束迭代器value
:查找的元素
2.2.2find_if
函數原型:
find_if(iterator beg, iterator end, _Pred);
按指定條件查找元素beg
:開始迭代器end
:結束迭代器_Pred
:函數或者謂詞(返回bool
類型的仿函數)
2.2.3adjacent_find
函數原型:
adjacent_find(iterator beg, iterator end);
:查找相鄰重複元素beg
:開始迭代器end
:結束迭代器
2.2.4binary_search
函數原型:
bool binary_search(iterator beg, iterator end, value);
:查找指定元素,返回bool
值beg
:開始迭代器end
:結束迭代器value
:查找的元素
- **注意:**在無序序列中不可用
2.2.5count
函數原型:
count(iterator beg, iterator end, value);
:統計元素出現次數beg
:開始迭代器end
:結束迭代器value
:要統計的元素
2.2.6count_if
函數原型:
count_if(iterator beg, iterator end, _Pred);
:按照條件統計元素出現次數beg
:開始迭代器end
:結束迭代器_Pred
:謂詞
2.3常用排序算法
算法簡介:
sort
:對容器內元素進行排序random_shuffle
:洗牌,指定範圍內的元素隨機調整次序merge
:容器元素合併,並儲存到另一個容器中reverse
:反轉指定範圍的元素
2.3.1sort
函數原型:
sort(iterator beg, iterator end, _Pred);
:按值查找元素,找到返回指定位置迭代器,找不到返回結束迭代器beg
:開始迭代器end
:結束迭代器_Pred
:謂詞
2.3.2random_shuffle
函數原型:
random_shuffle(iterator beg, iterator end);
:指定範圍內的元素隨機調整次序beg
:開始迭代器end
:結束迭代器
2.3.3merge
函數原型:
merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
:兩個容器合併,並儲存到另一個容器中beg1
:容器1開始迭代器end1
:容器1結束迭代器beg2
:容器2開始迭代器end2
:容器2結束迭代器dest
:目標容器開始迭代器
- 注意:兩個容器必須是有序的
2.3.4reverse
函數原型:
reverse(iterator beg, iterator end);
:反轉指定範圍的元素beg
:開始迭代器end
:結束迭代器
2.4常用拷貝和替換算法
算法簡介:
copy
:容器內指定範圍的元素拷貝到另一個容器中replace
:將容器內指定範圍的舊元素修改爲新元素replace_if
:容器內指定範圍滿足條件的元素替換爲新元素swap
:互換兩個容器的元素
2.4.1copy
函數原型:
copy(iterator beg, iterator end, iterator dest);
:按值查找元素,找到返回指定位置迭代器找不到返回結束迭代器位置beg
:容器開始迭代器end
:容器結束迭代器dest
:目標容器開始迭代器
2.4.2replace
函數原型:
replace(iterator beg, iterator end, oldValue, newValue);
:將區間內的舊元素替換爲新元素beg
:容器開始迭代器end
:容器結束迭代器oldValue
:舊元素newValue
:新元素
2.4.3replace_if
函數原型:
replace_if(iterator beg, iterator end, _Pred, newValue);
:按條件替換元素,滿足條件替換爲指定元素beg
:容器開始迭代器end
:容器結束迭代器_Pred
:謂詞newValue
:新元素
2.4.4swap
函數原型:
swap(container c1, container c2);
:互換兩個容器的元素c1
:容器1c2
:容器2
2.5常用算術生成算法
注意:
- 算術生成算法屬於小型算法,使用時包含頭文件
numeric
算法簡介:
accumulate
:計算容器元素累加和fill
:向容器中添加元素
2.5.1accumulate
函數原型:
accumulate(iterator beg, iterator end, value);
:計算容器元素累計總和beg
:容器開始迭代器end
:容器結束迭代器value
:開始累加的起始值
2.5.2fill
函數原型:
fill(iterator beg, iterator end, value);
:向容器中填充元素beg
:容器開始迭代器end
:容器結束迭代器value
:要填充的值
2.6常用集合算法
算法簡介:
set_intersection
:求兩個容器的交集set_union
:求兩個容器的並集set_difference
:求兩個容器的差集
2.6.1set_intersection
函數原型:
set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
:求兩個容器的交集beg1
:容器1開始迭代器end1
:容器1結束迭代器beg2
:容器2開始迭代器end2
:容器2結束迭代器dest
:目標容器開始迭代器
2.6.2set_union
函數原型:
-
set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
:求兩個容器的並集beg1
:容器1開始迭代器end1
:容器1結束迭代器beg2
:容器2開始迭代器end2
:容器2結束迭代器dest
:目標容器開始迭代器
-
注意:兩個集合必須是有序序列
2.6.3set_difference
函數原型:
-
set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
:求兩個容器的差集beg1
:容器1開始迭代器end1
:容器1結束迭代器beg2
:容器2開始迭代器end2
:容器2結束迭代器dest
:目標容器開始迭代器
-
注意:兩個集合必須是有序序列