C++編程提高——STL函數對象和常用算法

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:容器1
    • c2:容器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:目標容器開始迭代器
  • 注意:兩個集合必須是有序序列

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章