C++ stl 算法

目錄

 

1.概述

2常用算法簡介

2.1排序算法

2.2查找函數

2.3.刪除和替換算法

2.4 排列組合算法

2.5.數值算法

2.6.生成和異變算法

2.7.關係算法

2.8.集合算法

2.9 堆算法


1.概述

對於C++的stl,除了一些基本結構和一些自帶的函數,還有着大量的使用函數模板實現的算法支持stl。這些算法主要由<algorithm>,<numeric>組成。要使用stl的算法函數要包括頭文件<algorithm>,對於數值算法要包含<numeric>

2常用算法簡介

2.1排序算法

  • sort(),stable_sort()——對全體元素排序,不同的是stable_sort()會保證相等的元素的相對關係
  • partial_sort():對整個區間的元素進行排序,但只讓[beg,sortend)有序
  • nth_element:將第n個元素排好序,即只將第n個元素放好位置,將小於第n個元素的元素放在其左邊,將大於第n個元素的元素放在右邊(不過結果看起來是已全部重新排序,和sort無區別???)
  • reverse:將容器中的元素反向存儲(不可重載)
  • random_shuffle:對指定範圍內的元素隨機調整次序。
  • merge:合併兩個有序序列,存放到另一個序列
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional> // 定義了greater<int>()

using namespace std;

// 要注意的技巧
template <class T>
struct display
{
	void operator()(const T&x) const
	{
		cout << x << " ";
	}
};

// 如果想從大到小排序,可以採用先排序後反轉的方式,也可以採用下面方法:
// 自定義從大到小的比較器,用來改變排序方式
bool Comp(const int& a, const int& b) {
	return a > b;
}

int main(int argc, char* argv[])
{
	int iarr1[] = { 0, 1, 2, 3, 4, 5, 6, 6, 6, 7, 8 };
	vector<int> iv1(iarr1, iarr1 + sizeof(iarr1) / sizeof(int));
	vector<int> iv2(iarr1 + 4, iarr1 + 8); // 4 5 6 6
	vector<int> iv3(15);

	/*** merge: 合併兩個有序序列,存放到另一個序列 ***/
	// iv1和iv2合併到iv3中(合併後會自動排序)
	merge(iv1.begin(), iv1.end(), iv2.begin(), iv2.end(), iv3.begin());
	cout << "merge合併後: ";
	for_each(iv3.begin(), iv3.end(), display<int>());
	cout << endl;

	/*** random_shuffle: 對指定範圍內的元素隨機調整次序。 ***/
	int iarr2[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
	vector<int> iv4(iarr2, iarr2 + sizeof(iarr2) / sizeof(int));
	// 打亂順序  
	random_shuffle(iv4.begin(), iv4.end());
	cout << "random_shuffle打亂後: ";
	for_each(iv4.begin(), iv4.end(), display<int>());
	cout << endl;

	/*** reverse: 將指定範圍內元素重新反序排序。 ***/
	reverse(iv4.begin(), iv4.begin());
	cout << "reverse翻轉後: ";
	for_each(iv4.begin(), iv4.end(), display<int>());
	cout << endl;

	/*** partial_sort(): 對整個區間的元素進行排序,但只讓[beg,sortend)有序。 ***/
	partial_sort(iv4.begin(), iv4.begin()+3, iv4.end());
	cout << "partial_sort排序: ";
	for_each(iv4.begin(), iv4.end(), display<int>());
	cout << endl;

	random_shuffle(iv4.begin(), iv4.end());

	/*** nth_element: 將範圍內的序列重新排序。 ***/
	// 將小於iv.begin+5的放到左邊   
	nth_element(iv4.begin(), iv4.begin() + 5, iv4.end());
	cout << "nth_element重新排序後: ";
	for_each(iv4.begin(), iv4.end(), display<int>());
	cout << endl;


	/*** sort: 以升序重新排列指定範圍內的元素。 ***/
	// sort(iv4.begin(), iv4.end(), Comp); // 也可以使用自定義Comp()函數
	sort(iv4.begin(), iv4.end(), greater<int>());
	cout << "sort排序(倒序): ";
	for_each(iv4.begin(), iv4.end(), display<int>());
	cout << endl;

	/*** stable_sort: 與sort類似,不過保留相等元素之間的順序關係。 ***/
	int iarr3[] = { 0, 1, 2, 3, 3, 4, 4, 5, 6 };
	vector<int> iv5(iarr3, iarr3 + sizeof(iarr3) / sizeof(int));
	stable_sort(iv5.begin(), iv5.end(), greater<int>());
	cout << "stable_sort排序(倒序): ";
	for_each(iv5.begin(), iv5.end(), display<int>());
	cout << endl;

	return 0;
}

2.2查找函數

  • adjacent_find():返回範圍內第一組相鄰重複元素,,負責返回end()
  • count():統計範圍內選定元素個數
  • count_if:統計範圍內滿足條件的元素個數
  • binary_search:在有序序列中查找元素
  • equal_range:返回一對迭代器,第一個表示lower_bound,第二個表示upper_bround
  • find():在範圍內返回選定元素對應的額迭代器
  • find_if():在範圍內返回
  • search():在範圍內查找子序列的位置
  • search_n():在範圍內查找子序列重複n次的位置
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional> 

using namespace std;

int main(int argc, char* argv[])
{
	int iarr[] = { 0, 1, 2, 3, 4, 5, 6, 6, 6, 7, 8 };
	vector<int> iv(iarr, iarr + sizeof(iarr) / sizeof(int));

	/*** adjacent_find: 在iterator對標識元素範圍內,查找一對相鄰重複元素 ***/
	// 原型: _FwdIt adjacent_find(_FwdIt _First, _FwdIt _Last)
	cout << "adjacent_find: ";
	cout << *adjacent_find(iv.begin(), iv.end()) << endl;

	/*** count: 利用等於操作符,把標誌範圍內的元素與輸入值比較,返回相等元素個數。 ***/
	// 原型: count(_InIt _First, _InIt _Last, const _Ty& _Val)
	cout << "count(==6): ";
	cout << count(iv.begin(), iv.end(), 6) << endl;// 統計6的個數

	/*** count_if: 利用輸入的操作符,對標誌範圍內的元素進行操作,返回結果爲true的個數。 ***/
	// 原型: count_if(_InIt _First, _InIt _Last, _Pr _Pred)
	// 統計小於7的元素的個數 :9個
	cout << "count_if(<7): ";
	cout << count_if(iv.begin(), iv.end(), bind2nd(less<int>(), 7)) << endl;

	/*** binary_search: 在有序序列中查找value,找到返回true。 ***/
	// 原型: bool binary_search(_FwdIt _First, _FwdIt _Last, const _Ty& _Val)
	cout << "binary_search: ";
	cout << binary_search(iv.begin(), iv.end(), 4) << endl; // 找到返回true

	/*** equal_range: 功能類似equal,返回一對iterator,第一個表示lower_bound,第二個表示upper_bound。 ***/
	// 原型: equal_range(_FwdIt _First, _FwdIt _Last, const _Ty& _Val)
	pair<vector<int>::iterator, vector<int>::iterator> pairIte;
	pairIte = equal_range(iv.begin(), iv.end(), 3);
	cout << "pairIte.first:" << *(pairIte.first) << endl;// lowerbound 3   
	cout << "pairIte.second:" << *(pairIte.second) << endl; // upperbound 4

	/*** find: 利用底層元素的等於操作符,對指定範圍內的元素與輸入值進行比較。 ***/
	// 原型: _InIt find(_InIt _First, _InIt _Last, const _Ty& _Val)
	cout << "find: ";
	cout << *find(iv.begin(), iv.end(), 4) << endl; // 返回元素爲4的元素的下標位置

	/*** find_if: 使用輸入的函數代替等於操作符執行find。 ***/
	// 原型: _InIt find_if(_InIt _First, _InIt _Last, _Pr _Pred)
	cout << "find_if: " << *find_if(iv.begin(), iv.end(), bind2nd(greater<int>(), 2)) << endl; // 返回大於2的第一個元素的位置:3 

	/*** search: 給出兩個範圍,返回一個ForwardIterator,查找成功指向第一個範圍內第一次出現子序列的位置。 ***/
	// 原型: _FwdIt1 search(_FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2, _FwdIt2 _Last2)
	// 在iv中查找 子序列 2 3 第一次出現的位置的元素   
	int iarr3[3] = { 2, 3 };
	vector<int> iv3(iarr3, iarr3 + 2);
	cout << "search: " << *search(iv.begin(), iv.end(), iv3.begin(), iv3.end()) << endl;

	/*** search_n: 在指定範圍內查找val出現n次的子序列。 ***/
	// 原型: _FwdIt1 search_n(_FwdIt1 _First1, _FwdIt1 _Last1, _Diff2 _Count, const _Ty& _Val)
	// 在iv中查找 2個6 出現的第一個位置的元素   
	cout << "search_n: " << *search_n(iv.begin(), iv.end(), 2, 6) << endl;

	return 0;
}

2.3.刪除和替換算法

  • copy():複製序列
  • copy_backward():反向複製序列
  • iter_swap:交換兩個迭代器的值
  • remove:刪除指定範圍內所有等於指定元素的元素
  • remove_copy:將所有不匹配的元素複製到一個指定的容器
  • remove_if:刪除指定範圍內輸入操作結果爲true的所有元素
  • remove_copy_if:將所有不匹配元素拷貝到一個指定容器
  • replace:將指定範圍所有選定的元素替換成指定元素
  • replace_copy:將指定範圍所有選定的元素替換成指定元素,並複製到一個指定的容器
  • replace_if:將指定範圍內輸入操作結果爲true的所有元素替換成指定元素
  • replace_copy_if:將指定範圍內輸入操作結果爲true的所有元素替換成指定元素,並複製到一個指定的容器
  • swap:交換存儲在兩個對象中的值
  • swap_range:在指定範圍內的元素與另一個序列元素值進行交換
  • unique:清除序列中重複的元素
  • unique_copy:清除序列中重複的元素,並將結果輸入到另外一個容器中
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional> // 定義了greater<int>()

using namespace std;

template <class T>
struct display
{
	void operator()(const T&x) const
	{
		cout << x << " ";
	}
};

int main(int argc, char* argv[])
{
	int iarr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
	vector<int> iv1(iarr1, iarr1 + sizeof(iarr1) / sizeof(int));
	vector<int> iv2(9);

	/*** copy: 複製序列 ***/
	//  原型: _OutIt copy(_InIt _First, _InIt _Last,_OutIt _Dest)
	copy(iv1.begin(), iv1.end(), iv2.begin());
	cout << "copy(iv2): ";
	for_each(iv2.begin(), iv2.end(), display<int>());
	cout << endl;

	/*** copy_backward: 與copy相同,不過元素是以相反順序被拷貝。 ***/
	//  原型: _BidIt2 copy_backward(_BidIt1 _First, _BidIt1 _Last,_BidIt2 _Dest)
	copy_backward(iv1.begin(), iv1.end(), iv2.rend());
	cout << "copy_backward(iv2): ";
	for_each(iv2.begin(), iv2.end(), display<int>());
	cout << endl;

	/*** iter_swap:交換兩個迭代器的值***/
	// 原型:void iter_swap(_FwdIt1 _Left, _FwdIt2 _Right)
	iter_swap(iv2.begin(), iv2.end()-1);
	cout << "iter_swap(iv2.begin(), iv2.end()):";
	for_each(iv2.begin(), iv2.end(), display<int>());
	cout << endl;

	/*** remove: 刪除指定範圍內所有等於指定元素的元素。 ***/
	//  原型: _FwdIt remove(_FwdIt _First, _FwdIt _Last, const _Ty& _Val)
	remove(iv1.begin(), iv1.end(), 5); // 刪除元素5
	cout << "remove(iv1): ";
	for_each(iv1.begin(), iv1.end(), display<int>());
	cout << endl;

	/*** remove_copy: 將所有不匹配元素複製到一個制定容器,返回OutputIterator指向被拷貝的末元素的下一個位置。 ***/
	//  原型: 	_OutIt remove_copy(_InIt _First, _InIt _Last,_OutIt _Dest, const _Ty& _Val)
	vector<int> iv3(8);
	remove_copy(iv1.begin(), iv1.end(), iv3.begin(), 4); // 去除4 然後將一個容器的元素複製到另一個容器
	cout << "remove_copy(iv3): ";
	for_each(iv3.begin(), iv3.end(), display<int>());
	cout << endl;

	/*** remove_if: 刪除指定範圍內輸入操作結果爲true的所有元素。 ***/
	//  原型: _FwdIt remove_if(_FwdIt _First, _FwdIt _Last, _Pr _Pred)
	remove_if(iv3.begin(), iv3.end(), bind2nd(less<int>(), 6)); //  將小於6的元素 "刪除"
	cout << "remove_if(iv3): ";
	for_each(iv3.begin(), iv3.end(), display<int>());
	cout << endl;

	/*** remove_copy_if: 將所有不匹配元素拷貝到一個指定容器。 ***/
	// 原型: _OutIt remove_copy_if(_InIt _First, _InIt _Last,_OutIt _Dest, _Pr _Pred)
	//  將iv1中小於6的元素 "刪除"後,剩下的元素再複製給iv3
	remove_copy_if(iv1.begin(), iv1.end(), iv2.begin(), bind2nd(less<int>(), 4));
	cout << "remove_if(iv2): ";
	for_each(iv2.begin(), iv2.end(), display<int>());
	cout << endl;

	/*** replace:將指定範圍所有選定的元素替換成指定元素 ***/
	// 原型:void replace(_FwdIt _First, _FwdIt _Last,const _Ty& _Oldval, const _Ty& _Newval)
	replace(iv2.begin(), iv2.end(), 8, 5);
	cout << "replace(iv2.begin(), iv2.end(), 8, 5): ";
	for_each(iv2.begin(), iv2.end(), display<int>());
	cout << endl;

	/*** replace_copy:將指定範圍所有選定的元素替換成指定元素,並複製到一個指定的容器 ***/
	// 原型:_OutIt replace_copy(_InIt _First, _InIt _Last,	_OutIt _Dest, const _Ty& _Oldval, const _Ty& _Newval):
	vector<int> iv4(8);
	replace_copy(iv3.begin(), iv3.end(), iv4.begin(), 8, 5);
	cout << "replace_copy(iv3.begin(), iv3.end(), iv4.begin(), 8, 5): ";
	for_each(iv4.begin(), iv4.end(), display<int>());
	cout << endl;

	/*** replace_if:將指定範圍內輸入操作結果爲true的所有元素替換成指定元素 ***/
	// 原型:_OutIt replace_copy(_InIt _First, _InIt _Last,	_OutIt _Dest, const _Ty& _Oldval, const _Ty& _Newval):
	replace_if(iv3.begin(), iv3.end(), bind2nd(less<int>(), 7), 8);
	cout << "replace_if(iv3.begin(), iv3.end(), bind2nd(less<int>(), 7), 8): ";
	for_each(iv3.begin(), iv3.end(), display<int>());
	cout << endl;

	/***  replace_copy_if:將指定範圍內輸入操作結果爲true的所有元素替換成指定元素,並複製到一個指定的容器 ***/
	// 原型:_OutIt replace_copy_if(_InIt _First, _InIt _Last,_OutIt _Dest, _Pr _Pred, const _Ty& _Val):
	replace_copy_if(iv3.begin(), iv3.end(), iv4.begin(), bind2nd(less<int>(), 8), 9);
	cout << "replace_copy_if(iv3.begin(), iv3.end(), iv4.begin(), bind2nd(less<int>(), 8), 9): ";
	for_each(iv4.begin(), iv4.end(), display<int>());
	cout << endl;

	/*** swap:交換存儲在兩個對象中的值 ***/
	// 原型:void swap(vector<_Ty, _Alloc>& _Left, vector<_Ty, _Alloc>& _Right)
	swap(iv4, iv3);
	cout << "swap(iv4, iv3):iv4: ";
	for_each(iv4.begin(), iv4.end(), display<int>());
	cout << " iv3: ";
	for_each(iv3.begin(), iv3.end(), display<int>());
	cout << endl;

	/*** swap_range:在指定範圍內的元素與另一個序列元素值進行交換 ***/
	// 原型:swap_ranges(iv4.begin()+2,iv4.end()-2,iv2.begin()+2)
	swap_ranges(iv4.begin()+2,iv4.end()-2,iv2.begin()+2);
	cout << "swap_ranges(iv4.begin()+2,iv4.end()-2,iv2.begin()+2):iv4: ";
	for_each(iv4.begin(), iv4.end(), display<int>());
	cout << " iv2: ";
	for_each(iv2.begin(), iv2.end(), display<int>());
	cout << endl;

	/*** unique:清除序列中重複的元素 ***/
	// 原型:_FwdIt unique(_FwdIt _First, _FwdIt _Last)
	unique(iv4.begin(), iv4.end());
	cout << "unique(iv4.begin(), iv4.end()): ";
	for_each(iv4.begin(), iv4.end(), display<int>());
	cout << endl;;
	/*** unique_copy:清除序列中重複的元素,並將結果輸入到另外一個容器中 ***/
	unique_copy(iv4.begin(), iv4.end(),iv3.begin());
	cout << "unique_copy(iv4.begin(), iv4.end(),iv3.begin()): ";
	for_each(iv3.begin(), iv3.end(), display<int>());
	cout << endl;

	return 0;
}

2.4 排列組合算法

  • next_permutation:給出字典順序排序的下一個,例如abc->acb->bac->bca->cab->cba中選定字符串的下一個
  • prev_permutation:給出字典順序排序的上一個
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

template <class T>
struct display
{
	void operator()(const T&x) const
	{
		cout << x << " ";
	}
};

int main(int argc, char* argv[])
{
	int iarr[] = { 12, 17, 20, 22, 23, 30, 33, 40 };
	vector<int> iv(iarr, iarr + sizeof(iarr) / sizeof(int));

	/*** next_permutation: 取出當前範圍內的排列,並重新排序爲下一個字典序排列。***/
	//  原型: bool next_permutation(_BidIt _First, _BidIt _Last)
	// 生成下一個排列組合(字典序)   
	next_permutation(iv.begin(), iv.end());
	for_each(iv.begin(), iv.end(), display<int>());
	cout << endl;
	next_permutation(iv.begin(), iv.end());
	for_each(iv.begin(), iv.end(), display<int>());
	cout << endl;


	return 0;
}

2.5.數值算法

  • accumulate:將容器中的元素之和加到一個初始值上
  • partial_sum:創建一個新序列,其中每個元素代表該位置至指定開頭之間元素之和
  • inner_product:對兩個序列做內積
  • adjacent_difference:創建一個新序列,每個元素代表當前元素與上一個元素之差
#include <iostream>
#include <vector>
#include <numeric> // 數值算法
#include <iterator> // 定義了ostream_iterator

using namespace std;

int main(int argc, char* argv[])
{
	int arr[] = { 1, 2, 3, 4, 5 };
	vector<int> vec(arr, arr + 5);
	vector<int> vec2(arr, arr + 5);

	//  accumulate: iterator對標識的序列段元素之和,加到一個由val指定的初始值上。
	int temp;
	int val = 1;
	temp = accumulate(vec.begin(), vec.end(), val);
	cout << "accumulate(val = 1): " << temp << endl;

	// inner_product: 對兩個序列做內積(對應元素相乘,再求和)並將內積加到一個輸入的初始值上。
	// 這裏是:1*1 + 2*2 + 3*3 + 4*4 + 5*5
	val = 0;
	temp = inner_product(vec.begin(), vec.end(), vec2.begin(), val);
	cout << "inner_product(val = 0): " << temp << endl;

	// partial_sum: 創建一個新序列,其中每個元素值代表指定範圍內該位置前所有元素之和。
	// 第一次,1   第二次,1+2  第三次,1+2+3  第四次,1+2+3+4
	ostream_iterator<int> oit(cout, " "); // 迭代器綁定到cout上作爲輸出使用
	cout << "ostream_iterator: ";
	partial_sum(vec.begin(), vec.end(), oit);// 依次輸出前n個數的和
	cout << endl;
	// 第一次,1   第二次,1-2  第三次,1-2-3  第四次,1-2-3-4
	cout << "ostream_iterator(minus): ";
	partial_sum(vec.begin(), vec.end(), oit, minus<int>());// 依次輸出第一個數減去(除第一個數外到當前數的和)
	cout << endl;

	// adjacent_difference: 創建一個新序列,新序列中每個新值代表當前元素與上一個元素的差。
	// 第一次,1-0   第二次,2-1  第三次,3-2  第四次,4-3
	cout << "adjacent_difference: ";
	adjacent_difference(vec.begin(), vec.end(), oit); // 輸出相鄰元素差值 後面-前面
	cout << endl;
	// 第一次,1+0   第二次,2+1  第三次,3+2  第四次,4+3
	cout << "adjacent_difference(plus): ";
	adjacent_difference(vec.begin(), vec.end(), oit, plus<int>()); // 輸出相鄰元素差值 後面-前面 
	cout << endl;

	return 0;
}

2.6.生成和異變算法

  • fill:將輸入值賦給標誌範圍內的元素
  • fill_n:將輸入值賦給first到first+n範圍內的所有元素
  • for_each:用指定函數依次對指定範圍內所有元素進行迭代訪問
  • generate: 連續調用輸入的函數來填充指定的範圍
  • generate_n: 與generate函數類似,填充從指定iterator開始的n個元素。
  • transform: 將輸入的操作作用與指定範圍內的每個元素,併產生一個新的序列
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>

using namespace std;

template <class T>
struct display
{
	void operator()(const T&x) const
	{
		cout << x << " ";
	}
};
//  作用類似於上面結構體,只不過只能顯示int類型的數據
void printElem(int& elem)
{
	cout << elem << " ";
}

template<class T>
struct plus2
{
	void operator()(T&x)const
	{
		x += 2;
	}

};

class even_by_two
{
private:
	static int _x; //  注意靜態變量   
public:
	int operator()()const
	{
		return _x += 2;
	}
};
int even_by_two::_x = 0; //  初始化靜態變量

int main(int argc, char* argv[])
{
	int iarr[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
	vector<int> iv(iarr, iarr + sizeof(iarr) / sizeof(int));

	/*** fill: 將輸入值賦給標誌範圍內的所有元素。 ***/
	//  原型: void fill(_FwdIt _First, _FwdIt _Last, const _Ty& _Val)  
	fill(iv.begin(), iv.end(), 5);
	cout << "fill: ";
	for_each(iv.begin(), iv.end(), display<int>());
	cout << endl;

	/*** fill_n: 將輸入值賦給first到first+n範圍內的所有元素。 ***/
	//  原型: _OutIt fill_n(_OutIt _Dest, _Diff _Count, const _Ty& _Val)
	fill_n(iv.begin(), 4, 3); //  賦4個3給iv 
	cout << "fill_n: ";
	for_each(iv.begin(), iv.end(), display<int>());
	cout << endl;

	/*** for_each: 用指定函數依次對指定範圍內所有元素進行迭代訪問,返回所指定的函數類型。 ***/
	//  原型: _Fn1 for_each(_InIt _First, _InIt _Last, _Fn1 _Func)
	for_each(iv.begin(), iv.end(), plus2<int>()); //  每個元素+2
	cout << "for_each: ";
	for_each(iv.begin(), iv.end(), printElem); //  輸出
	cout << endl;

	/*** generate: 連續調用輸入的函數來填充指定的範圍。 ***/
	//  原型: void generate(_FwdIt _First, _FwdIt _Last, _Fn0 _Func)
	//  使用even_by_two()函數返回的值,來填充容器iv
	generate(iv.begin(), iv.end(), even_by_two());
	cout << "generate: ";
	for_each(iv.begin(), iv.end(), display<int>());
	cout << endl;

	/*** generate_n: 與generate函數類似,填充從指定iterator開始的n個元素。 ***/
	//  原型: _OutIt generate_n(_OutIt _Dest, _Diff _Count, _Fn0 _Func)
	//  使用even_by_two()函數返回的值,來填充容器iv的前三個值
	generate_n(iv.begin(), 3, even_by_two());
	cout << "generate_n: ";
	for_each(iv.begin(), iv.end(), display<int>()); //  由於_X是static 所以接着 增長
	cout << endl;

	/*** transform: 將輸入的操作作用與指定範圍內的每個元素,併產生一個新的序列。 ***/
	//  原型: _OutIt transform(_InIt _First, _InIt _Last, _OutIt _Dest, _Fn1 _Func)
	// 容器的所有值全部減2
	transform(iv.begin(), iv.end(), iv.begin(), bind2nd(minus<int>(), 2));
	cout << "transform: ";
	for_each(iv.begin(), iv.end(), display<int>()); //  由於_X是static 所以接着 增長
	cout << endl;

	return 0;
}

2.7.關係算法

  • equal: 如果兩個序列在標誌範圍內元素都相等,返回true。
  • includes: 判斷第一個指定範圍內的所有元素是否都被第二個範圍包含,使用底層元素的<操作符,成功返回true。重載版本使用用戶輸入的函數。
  • max: 返回兩個元素中較大一個。重載版本使用自定義比較操作。
  • min: 返回兩個元素中較小一個。重載版本使用自定義比較操作。
  • max_element: 返回一個ForwardIterator,指出序列中最大的元素。重載版本使用自定義比較操作。
  • min_element: 返回一個ForwardIterator,指出序列中最小的元素。重載版本使用自定義比較操作。
  • mismatch: 並行比較兩個序列,指出第一個不匹配的位置,返回一對iterator,標誌第一個不匹配元素位置。如果都匹配,返回每個容器的last。重載版本使用自定義的比較操作。
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main(int argc, char* argv[])
{
	int iarr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	vector<int> iv1(iarr, iarr + 5);
	vector<int> iv2(iarr, iarr + 9);

	//  equal: 如果兩個序列在標誌範圍內元素都相等,返回true。
	cout << "equal: " << equal(iv1.begin(), iv1.end(), iv2.begin()) << endl;//  1 表示相等,因爲只比較跟 iv1長度大小的數組      

	// includes: 判斷第一個指定範圍內的所有元素是否都被第二個範圍包含,使用底層元素的<操作符,成功返回true。
	// 判斷判斷iv2中元素是否都出現在iv1中
	cout << "includes: " << includes(iv1.begin(), iv1.end(), iv2.begin(), iv2.end()) << endl;

	// max: 返回兩個元素中較大一個。
	cout << "max: " << max(iv1[0], iv1[1]) << endl;
	// min: 返回兩個元素中較小一個。
	cout << "min: " << min(iv1[0], iv1[1]) << endl;

	// max_element: 返回一個ForwardIterator,指出序列中最大的元素。
	cout << "max_element: " << *max_element(iv1.begin(), iv1.end()) << endl;
	// min_element: 返回一個ForwardIterator,指出序列中最小的元素。
	cout << "min_element: " << *min_element(iv1.begin(), iv1.end()) << endl;

	//  mismatch: 並行比較兩個序列,指出第一個不匹配的位置,返回一對iterator,標誌第一個不匹配元素位置。如果都匹配,返回每個容器的last。
	pair<vector<int>::iterator, vector<int>::iterator> pa;
	pa = mismatch(iv1.begin(), iv1.end(), iv2.begin());
	if (pa.first == iv1.end()) //  true 表示相等,因爲只比較跟iv1長度大小的數組 
		cout << "第一個向量與第二個向量匹配" << endl;
	else
	{
		cout << "兩個向量不同點--第一個向量點:" << *(pa.first) << endl; // 這樣寫很危險,應該判斷是否到達end   
		cout << "兩個向量不同點--第二個向量點:" << *(pa.second) << endl;
	}

	return 0;
}

2.8.集合算法

  • set_union: 構造一個有序序列,包含兩個序列中所有的不重複元素。重載版本使用自定義的比較操作。
  • set_intersection: 構造一個有序序列,其中元素在兩個序列中都存在。重載版本使用自定義的比較操作。
  • set_difference: 構造一個有序序列,該序列僅保留第一個序列中存在的而第二個中不存在的元素。重載版本使用自定義的比較操作。
  • set_symmetric_difference: 構造一個有序序列,該序列取兩個序列的對稱差集(並集-交集)。
#include <iostream>
#include <set>
#include <algorithm>
#include <iterator> 

using namespace std;

template <class T>
struct display
{
	void operator()(const T&x) const
	{
		cout << x << " ";
	}
};

int main(int argc, char* argv[])
{
	int iarr1[] = { 1, 3, 5, 7, 9, 11 };
	int iarr2[] = { 1, 1, 2, 3, 5, 8, 13 };

	multiset<int> s1(iarr1, iarr1 + 6);
	multiset<int> s2(iarr2, iarr2 + 7);
	cout << "s1: ";
	for_each(s1.begin(), s1.end(), display<int>());
	cout << endl;
	cout << "s2: ";
	for_each(s2.begin(), s2.end(), display<int>());
	cout << endl;

	/*** set_union: 構造一個有序序列,包含兩個序列中所有的不重複元素。 ***/
	//  原型: _OutIt set_union(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	cout << "union of s1 and s2: ";
	// 兩個集合合併,相同元素個數取 max(m,n)。   
	set_union(s1.begin(), s1.end(), s2.begin(), s2.end(), ostream_iterator<int>(cout, " "));
	cout << endl;

	/*** set_intersection: 構造一個有序序列,其中元素在兩個序列中都存在。 ***/
	//  原型: _OutIt set_union(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	cout << "Intersection of s1 and s2: ";
	// 兩個集合交集,相同元素個數取 min(m,n).  
	set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), ostream_iterator<int>(cout, " "));
	cout << endl;

	/*** set_difference: 構造一個有序序列,該序列僅保留第一個序列中存在的而第二個中不存在的元素。 ***/
	//  原型: _OutIt set_union(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	cout << "Intersection of s1 and s2: ";
	// 兩個集合差集 就是去掉S1中 的s2   
	set_difference(s1.begin(), s1.end(), s2.begin(), s2.end(), ostream_iterator<int>(cout, " "));
	cout << endl;

	/*** set_symmetric_difference: 構造一個有序序列,該序列取兩個序列的對稱差集(並集-交集)。 ***/
	//  原型: _OutIt set_union(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
	cout << "Intersection of s1 and s2: ";
	// 兩個集合對稱差集:就是取兩個集合互相沒有的元素 。兩個排序區間,元素相等指針後移,不等輸出小的並前進   
	// 相同元素的個數 abs(m-n)   
	set_symmetric_difference(s1.begin(), s1.end(), s2.begin(), s2.end(), ostream_iterator<int>(cout, " "));
	cout << endl;

	return 0;
}

2.9 堆算法

  • make_heap: 把指定範圍內的元素生成一個堆。保證最大值在所給範圍的最前面,其他值的位置不確定,重載版本使用自定義比較操作。
  • pop_heap: 將堆頂(所給範圍的最前面)元素移動到所給範圍的最後,並且將新的最大值置於所給範圍的最前面
  • push_heap: 假設first到last-1是一個有效堆,要被加入到堆的元素存放在位置last-1,重新生成堆。在指向該函數前,必須先把元素插入容器後。重載版本使用指定的比較操作。
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

template <class T>
struct display
{
	void operator()(const T&x) const
	{
		cout << x << " ";
	}
};

int main(int argc, char* argv[])
{
	int iarr[] = { 9,5, 1, 7, 8 };
	vector<int> iv(iarr, iarr + sizeof(iarr) / sizeof(int));

	/*** make_heap: 把指定範圍內的元素生成一個堆。 ***/
	//  原型: void make_heap(_RanIt _First, _RanIt _Last)
	make_heap(iv.begin(), iv.end());
	cout << "make_heap: ";
	for_each(iv.begin(), iv.end(), display<int>());
	cout << endl;

	/*** pop_heap: 並不真正把最大元素從堆中彈出,而是重新排序堆。 ***/
	//  原型: void pop_heap(_RanIt _First, _RanIt _Last)
	pop_heap(iv.begin(), iv.end());
	iv.pop_back();
	cout << "pop_heap: ";
	for_each(iv.begin(), iv.end(), display<int>());
	cout << endl;

	/*** push_heap: 假設first到last-1是一個有效堆,要被加入到堆的元素存放在位置last-1,重新生成堆。 ***/
	//  原型: void push_heap(_RanIt _First, _RanIt _Last)
	iv.push_back(6);
	push_heap(iv.begin(), iv.end());
	cout << "push_heap: ";
	for_each(iv.begin(), iv.end(), display<int>());
	cout << endl;

	return 0;
}

 

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