一 算法概述
算法都是函数,具体来说是函数模版,且是全局函数模版
算法有很多种:例如查找,排序等,上百种算法
算法形参的类型一般都是比较固定的,算法的前两个形参的类型,一般都是迭代器类型。用来表示容器中元素的一个区间。例如我们对vector中的第2到第5个元素进行排序,因此要知道vector 2-5个元素的区间,而迭代器的作用就是指向 容器的区间。因此算法的前两个元素都是迭代器。
假设我们要将vector的全部元素进行排序,那么第一个元素应该是 vec.begin(),第二个参数应该是vec.end();如下图:
也就是说,在对元素的处理 。参数应该是 前闭后开的区间
设计成前闭后开这种模式是有好处的:
算法只要判断迭代器只要等于后边这个开区间,就表示迭代结束。
如果第一个参数,等于第二个参数,说明这是一个空区间。
算法:可以看成是一种搭配迭代器使用的全局函数,算法跟具体的容器没关联,只跟迭代器有关联。这意味着:只需要根据迭代器来开发算法,不需要理会具体的容器,从而增加了算法代码开发的弹性;
注意,但是对于
二 算法内部一些处理
算法会根据传递进来的迭代器来分析出迭代器种类(5种之一),不同的种类的迭代器,算法会有不同的处理,要编写不同的代码来应对。
这种编写不同的代码来处理不同种类的迭代器,能够直接影响算法的执行效率。
这也是stl 内部为什么要给这些迭代器做一个分类的目的。
三。常用算法一些特性
当有些容器有自己的成员函数,假设这个成员函数名字叫做find
算法中也有一个同名的函数,叫做find。
那么我们要优先使用 容器自己的成员函数。
三 for_each
在标头 |
#include <algorithm>
void myfunc(int value) {
cout << "value = " << value << endl;
};
void main() {
//for_each工作原理:不断地迭代给进来的两个迭代器之间的元素,然后拿到这个元素,以这个元素为实参来调用myfunc(元素)
vector<int> myvector = { 20,90,789 };
for_each(myvector.begin(), myvector.end(),myfunc);
}
四 find
#include <algorithm>
void main() {
//find 算法,从迭代器区间找,想要的值
vector<int> myvector = { 20,90,789 };
vector<int>::iterator itfind = find(myvector.begin(), myvector.end(), 400);
if (itfind!=myvector.end()) {
//找到了
cout << "找到了 *itfind = " << *itfind << endl;
}
else {
//没找到
cout << "没找到 400 " << endl;
}
//找中间元素,注意 迭代器的前后元素包含。
vector<int> myvector1 = { 20,30,40,50,60,800,90890,989898 };
vector<int>::iterator itfind1 = find(myvector1.begin(), myvector1.begin()+6, 90890);//注意这里,是从开始位置查找,查找90890之前。不包括90890
//注意判断条件发生变化
if (itfind1 != myvector1.begin() + 6) {
//找到了
cout << "找到了 *itfind = " << *itfind1 << endl;
}
else {
//没找到
cout << "没找到 90890,当前 *itfind= " << *itfind1 << endl;
}
//找中间元素,注意 迭代器的前后元素包含
vector<int>::iterator itfind2 = find(myvector1.begin(), myvector1.begin() + 7, 90890);//注意这里,是从开始位置查找,查找90890之前。不包括90890
if (itfind2 != myvector1.begin() + 7) {
//找到了
cout << "找到了 *itfind2 = " << *itfind2 << endl;
}
else {
//没找到
cout << "没找到 90890,当前 *itfind2= " << *itfind2 << endl;
}
}
五 find_if
要求最后一个参数,是可调用对象,在条件成立的时候,返回true。
如下的写法是使用lambda表达式做为可调用对象。
#include <algorithm>
//find_if
void main() {
vector<int> myvector1 = { 20,30,40,50,60,800,90890,989898 };
auto result = find_if(myvector1.begin(), myvector1.end(), [](int val) {
if (val>899999999) {
return true;
}
return false;
});
if (result != myvector1.end()) {
//找到了
cout << "找到了 result = " << *result << endl;
}
else {
//没有找到
cout << "nmeiyou 找到 " << endl;
}
}
六 sort
sort 是排序的,如果容器内部的排序通过容器内部完成的,那么一般都不能用sort算法。
特别是红色框框的部分,一般都不能使用。
像list这种,和forward_list这种,一般都会有自己的成员函数sort,也不需要 算法的sort
//组定义 sort 排序
bool myfuncsort(int i, int j) {
return i > j;
}
void main() {
vector<int> myvector1 = { 30,20,800,60,90890,989898 };
sort(myvector1.begin(),myvector1.end());//缺省是从小到大排序
for (auto it = myvector1.begin(); it != myvector1.end();++it) {
cout << *it << " ";
}
//20 30 60 800 90890 989898
cout << "" << endl;
sort(myvector1.begin(), myvector1.end(), myfuncsort);
for (auto it = myvector1.begin(); it != myvector1.end(); ++it) {
cout << *it << " ";
}
//989898 90890 800 60 30 20
}