19.6 算法简介、内部处理与使用范例

比如:查找、排序等等,数十甚至上百个算法,数量不断上涨;
算法的前两个形参的类型,一般都是迭代器类型,用来表示容器中的元素一个区间。

一: 算法简介

算法名(iter_begin, iter_end)传递进去的应该是一个前闭后开的区间[begin(), end()]。

前闭后开区间的好处一般认为有两条:
<1>算法只要判断迭代器只要等于后面这个开区间,那就表示迭代结束;
<2>如果第一个形参等于第二个形参,也就是iter_begin == iter_end;就表示是一个空区间;

算法是一种搭配迭代器来使用的全局函数;算法和具体容器没有关联,只和迭代器有关联,只需要根据迭代器来开发算法,不需要确定具体容器。

算法这种泛型编程方式,增加了灵活性,但是缺失了直观性;某些数据结构(某些容器的迭代器)和算法之间的兼容性也不是特别好。

stl中到底有哪些算法《c++标准库 第二版》11.2.2,“算法分门别类”;做概览了解。

#include <list>
#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
	cout << "begin" << endl;
	list<int> mylist = { 100, 200, 300 };
	list<int>::iterator iterbegin = mylist.begin();
	list<int>::iterator iterend = mylist.end();  //最后一个元素的下一个位置
	cout << "end" << endl;
	return 0;
}

二:算法内部一些处理

算法会根据传递进来的迭代器来分析出迭代器种类(五种之一),不同种类的迭代器,算法会有不用的处理,要编写不同的代码处理,这种编写不同代码来处理不同种类的迭代器,能够直接影响到算法的执行效率。(效率是一个很重要的指标)这也就是stl内部为什么要给这些迭代器做分类的目的。

三:一些典型算法使用范例

算法头文件包要包含进来:#include
当有成员函数和全局函数(算法)同时存在时,优先考虑使用同名的成员函数,如果没有同名的成员函数,才考虑使用全局函数。

1、foreach

第二十章高级话题与新标准第八节

#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

void myfunc(int i)  //参数类型是容器中的元素类型
{
	cout << i << endl;
}

void func()
{
	vector<int> myvector = { 10, 20, 30, 40, 50, 60 };
	//for_each工作原理:不断的迭代给进来的两个迭代器之间的元素,然后拿到这个元素,以这个元素为实参来调用myfunc(元素)
	for_each(myvector.begin(), myvector.end(), myfunc);  //myfunc是可调用对象
}

int main()
{
	cout << "begin" << endl;
	func();
	cout << "end" << endl;
	return 0;
}
template<typename InputIterator, typename Function>
Function for_each(InputIterator first, InputIterator last, Function f)
{
	for (; first != last; ++first)
	{
		f(*first);
	}
	return f;
}

这段代码表明2个问题:
<1>算法区分迭代器种类,这个种类决定着某些算法的效率,InputIterator
<2>f(*first):这是个可调用对象;第20章第一节

2、find和find_if

#include <map>
#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

void func()
{
	vector<int> myvector = { 10, 20, 30, 40, 50 };
	vector<int>::iterator finditer = find(myvector.begin(), myvector.end(), 400);
	if (finditer != myvector.end())  //判断是否等于find的第二个参数,等于就没找到,不等于就找到了
	{
		//找到了
	}
	else
	{
		//没找到
	}

	map<int, string> mymap;
	mymap.insert(std::make_pair(1, "老王"));
	mymap.insert(std::make_pair(2, "老类"));
	auto iter = mymap.find(2);  //优先使用自己的成员函数
	if (iter != mymap.end())
	{
		//找到
		printf("编号为%d,名字为%s\n", iter->first, iter->second.c_str());
	}

	//find_if演示
	auto result = find_if(myvector.begin(), myvector.end(), [](int val)
		{
			if (val > 15)
			{
				return true;  //停止遍历
			}
	return false;
		});
	if (result == myvector.end())
	{
		cout << "没找到" << endl;
	}
	else
	{
		cout << "找到了,结果为:" << *result << endl;
	}
}

int main()
{
	cout << "begin" << endl;
	func();
	cout << "end" << endl;
	return 0;
}

3、sort

#include <map>
#include <list>
#include <vector>
#include <iostream>
#include <algorithm>
#include <unordered_set>

using namespace std;


bool myfunc(int i, int j)
{
	//return i < j;  //从小到大排序
	return i > j;  //从大到小排序
}

void func()
{
	vector<int> myvector = { 50, 15, 80, 30, 46 };
	sort(myvector.begin(), myvector.end());  //缺省按照从小到大的顺序排列的
	sort(myvector.begin(), myvector.begin() + 3);  //只有前三个元素参与排序:15,50,80,30,46
	//若要从大到小排序,我们可以写自定义的比较函数,函数返回bool
	sort(myvector.begin(), myvector.end(), myfunc);

	for (auto iter = myvector.begin(); iter != myvector.end(); ++iter)
	{
		cout << *iter << endl;
	}

	cout << "-------------------------------" << endl;

	//试试list
	list<int> mylist = { 50, 15, 80, 30, 46 };
	mylist.sort(mylist);
	for (auto iter = mylist.begin(); iter != mylist.end(); ++iter)
	{
		cout << *iter << endl;
	}

	map<int, string> mymap;
	mymap.insert(std::make_pair(50, "老王"));
	mymap.insert(std::make_pair(50, "老李"));
	mymap.insert(std::make_pair(50, "老赵"));
	//sort(mymap.begin(), mymap.end());  //不让排序,编译报错

	unordered_set<int> myset = { 50, 15, 80, 30, 46 };
	sort(myset.begin(), myset.end());  //不让排序,编译报错
}


int main()
{
	cout << "begin" << endl;
	func();
	cout << "end" << endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值