参看内容: 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类似,遍历所有元素,但可对容器的元素进行修改