1. 程式人生 > >常用演算法(Algorithm)概述

常用演算法(Algorithm)概述

參看內容: VC知識庫

演算法(Algorithm)的簡介

演算法部分主要由標頭檔案<algorithm><numeric><functional> 組成。

  • <algorithm>是所有STL標頭檔案中最大的一個,其中常用到的功能範圍涉及到比較、交換、查詢、遍歷操作、複製、修改、反轉、排序、合併等等。

  • <numeric>體積很小,只包括幾個在序列上面進行簡單數學運算的模板函式,包括加法和乘法在序列上的一些操作。

  • <functional>中則定義了一些模板類,用以宣告函式物件。

演算法(Algorithm)的概要

  • 常用的查詢演算法:
adjacent_find()( adjacent 是鄰近的意思),binary_search(),count(),
count_if(),equal_range(),find(),find_if()。
  • 常用的排序演算法:
merge(),sort(),random_shuffle()(shuffle是洗牌的意思) ,reverse()。
  • 常用的拷貝和替換演算法:
copy(), replace(),
replace_if(),swap()
  • 常用的算術和生成演算法:
accumulate()( accumulate 是求和的意思),fill(),。
  • 常用的集合演算法:
set_union(),set_intersection(),
set_difference()。
  • 常用的遍歷演算法:
for_each(), transform()( transform 是變換的意思)

常用的查詢演算法

adjacent_find()
在iterator對標識元素範圍內,查詢一對相鄰重複元素,找到則返回指向這對元素的第一個元素的迭代器。否則返回past-the-end。

例如:vecInt是用vector<int>宣告的容器,現已包含1,2,2,4,5元素。
vector<int>::iterator it=adjacent_find(vecInt.begin(),vecInt.end());
此時 *it == 2

binary_search
在有序序列中查詢value,找到則返回true。

注意:在無序序列中,不可使用。

例如: setInt是用set<int>宣告的容器,現已包含1,3,5,7,9元素。
bool bFind = binary_search(setInt.begin(),setInt.end(),5);
此時 bFind == true

count
利用等於操作符,把標誌範圍內的元素與輸入值比較,返回相等的個數。
count_if
利用輸入的函式,對標誌範圍內的元素進行比較操作,返回結果為true的個數。

例如:vecInt是用vector<int>宣告的容器,已包含1,3,5,7,9元素,現要求求出大於等於3的元素個數

//先定義比較函式
bool GreaterThree(int iNum)
{
	if(iNum>=3)
	{
		return true;
	}
	else
	{
		return false;
	}
}

int iCount = count_if(vecIntA.begin(), vecIntA.end(), GreaterThree);
//此時iCount == 4

equal_range
返回一對 iterator,第一個表示 lower_bound,第二個表示 upper_bound
find
利用底層元素的等於操作符,對指定範圍內的元素與輸入值進行比較。當匹配時,結束搜尋,返回該元素的迭代器。

例如: vecInt是用vector<int>宣告的容器,已包含1,3,5,7,9
vector<int>::iterator it = find(vecInt.begin(),vecInt.end(),5);
此時*it == 5

find_if
使用輸入的函式代替等於操作符執行find。返回被找到的元素的迭代器。

例如:vecInt是用vector<int>宣告的容器,已包含1,3,5,3,9元素。現要找出第一個大於等於3的元素的迭代器。

vector<int>::iterator it = find_if(vecInt.begin(),vecInt.end(),GreaterThree);
此時 *it==3, *(it+1)==5, *(it+2)==3, *(it+3)==9

常用的排序演算法

以下是排序和通用演算法:提供元素排序策略

merge
合併兩個有序序列,存放到另一個序列。

例如:vecIntA,vecIntB,vecIntC是用vector<int>宣告的容器,vecIntA已包含1,3,5,7,9元素,vecIntB已包含2,4,6,8元素
vecIntC.resize(9); //擴大容量
merge(vecIntA.begin(),vecIntA.end(),vecIntB.begin(),vecIntB.end(),vecIntC.begin());

此時vecIntC就存放了按順序的1,2,3,4,5,6,7,8,9九個元素

sort
以預設升序的方式重新排列指定範圍內的元素。若要改排序規則,可以輸入比較函式。

例如: vecInt是用vector<int>宣告的容器,已包含2,1,4,3,6,5元素
sort(vecInt.begin(),vecInt.end());
此時,vecInt包含了1,2,3,4,5,6元素。
如果vector<T>,T是自定義型別,則要提供T型別的比較函式。

學生類有學號跟姓名的屬性,有一個存著學生物件的vector容器,要使該容器按學號升序排序。

//學生類
Class CStudent:
{
public:
	CStudent(int iID, string strName) {m_iID=iID;  m_strName=strName; }
          
	int m_iID;
	string m_strName;
}

//學號比較函式
bool Compare(const CStudent &stuA,const CStudent &stuB)
{
 	return (stuA.m_iID<strB.m_iID);
}

void main()
{
	vector<CStudent> vecStu;
	vecStu.push_back(CStudent(2,"老二"));
	vecStu.push_back(CStudent(1,"老大"));
	vecStu.push_back(CStudent(3,"老三"));
	vecStu.push_back(CStudent(4,"老四"));
	sort(vecStu.begin(),vecStu.end(),Compare);
	//  此時,vecStu容器包含了按順序的"老大物件","老二物件","老三物件","老四物件"
}
random_shuffle
對指定範圍內的元素隨機調整次序。
reverse
對指定範圍內元素重新反序排序。

常用的拷貝和替換演算法

copy
複製序列

例如:vecIntA,vecIntB是用vector<int>宣告的物件,vecIntA已包含1,3,5,7,9元素。

vecIntB.resize(5);
copy(vecIntA.begin(),vecIntA.end(),vecIntB.begin());

此時vecIntB也包含了1,3,5,7,9元素

replace(beg,end,oldValue,newValue)
將指定範圍內的所有等於oldValue的元素替換成newValue。
replace_if
將指定範圍內所有操作結果為true的元素用新值替換。

用法舉例:
replace_if(vecIntA.begin(),vecIntA.end(),GreaterThree,newVal)
其中vecIntA是用vector<int>宣告的容器

GreaterThree 函式的原型是 bool GreaterThree(int iNum)

swap
交換兩個容器的元素

常用的算術與生成演算法

accumulate
對指定範圍內的元素求和,然後結果再加上一個由val指定的初始值
fill
將輸入值賦給標誌範圍內的所有元素。

常用的集合演算法

set_union
構造一個有序序列,包含兩個有序序列的並集。
set_intersection
構造一個有序序列,包含兩個有序序列的交集。
set_difference
構造一個有序序列,該序列保留第一個有序序列中存在而第二個有序序列中不存在的元素。

常用的遍歷演算法

for_each
用指定函式依次對指定範圍內所有元素進行迭代訪問。該函式不得修改序列中的元素
transform
與for_each類似,遍歷所有元素,但可對容器的元素進行修改