C++笔记(四) 算法

一、算法概述

  1. 算法部分主要头文件<algorithm>,<numeric>,<functional>:<algorithm>是所有STL头文件中最大的一个,常用功能范围有比较、交换、查找、遍历操作、复制、修改、反转、排序、合并;<numeric>体积很小,只包括几个在序列上面进行简单数学运算的模板函数,包括加法和乘法在序列上的一些操作;<functional>中定义了一些模板类,用以声明函数对象。

  2. 算法分类:操作对象,直接改变容器的内容,将原容器的内容复制一份,修改其副本,然后传回该附本。非可辨序列算法:指不直接修改其所操作的容器内容的算法(计数算法、搜索算法、比较算法);可变序列算法:指可以修改他们所操作的内容的算法(删除算法、修改算法、排序算法)

  3. 算法中的函数对象和谓词:

  4. 函数对象--》重载函数调用操作符的类,其对象常称为函数对象,即他们是行为类似函数的对象,一个类对象,表现出一个函数的特征,就是通过“对象名+(参数列表)”方式使用一个类对象,如果没有上下文,完全可以把它看作一个函数对待。这是通过重载类的operator()来实现的。“在标准库中的很对算法都可以使用函数对象或者函数来作为自定回调行为。---实现了数据类型和算法的分离

分清楚STL算法返回的值是迭代器还是谓词(函数对象)是stl算法入门的重要点

预定义函数对象:标准模板库STL提前定义了很多预定义函数对象, #include <functional>必须包含;

  1. 谓词--》一元函数对象,函数参数1个;二元函数参数对象,函数参数2个。一元谓词:函数参数一个,函数返回值是bool类型,可以作为一个判断式;谓词可以是一个仿函数,也可以是一个回调函数;二元位置,函数参数2个,函数返回值是bool类型。

 

5.函数适配器

二、STL常用的算法

  1. for_each()
  2. for_each():用指定函数一次对指定范围内所有元素进行迭代访问,该函数不得修改序列中的元素。for_each()的第三个参数,函数对象做函数参数,函数对象做返回值。
    #include <iostream>
    
    using namespace std;
    
    #include "string"
    #include "set"
    #include <vector>
    #include <list>
    #include <algorithm>
    #include "functional"
    
    void printV(vector<int> &v)
    {
    	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
    	{
    		cout << *it << "\t";
    	}
    }
    void showElem(int &n)
    {
    	cout << n << "\t";
    }
    class CMyShow
    {
    
    public :
    	CMyShow()
    	{
    		num = 0;
    	}
    	void operator()(int &n)
    	{
    		cout << n << "\t";
    		num++;
    	}
    	void printV()
    	{
    		cout << num << endl;
    	}
    private :
    	int num;
    };
    void main41()
    {
    	vector<int> v1;
    	v1.push_back(1);
    	v1.push_back(3);
    	v1.push_back(5);
    	printV(v1);
    	cout << endl;
    	for_each(v1.begin(), v1.end(), showElem);
    	cout << endl;
    	CMyShow mya;
    	CMyShow my1=for_each(v1.begin(), v1.end(), mya);
    	cout << endl;
    	my1.printV();//my1和mya是两个不同的对象
    	mya.printV();
    }
    
    void main()
    {
    	main41();
    	cout << endl;
    	system("pause");
    }

     

  3. transform():与for_each类似,遍历所有元素,但可对容器的元素进行修改。他可以把一个容器的呀U尿素,通过op,变换到另一个容器中(同一个容器中);也可以把两个容器的元素,通过op,变换到另一个容器中。
    #include <iostream>
    
    using namespace std;
    
    #include "string"
    #include "set"
    #include <vector>
    #include <list>
    #include <algorithm>
    #include "functional"
    #include "iterator"
    void printV(vector<int> &v)
    {
    	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
    	{
    		cout << *it << "\t";
    	}
    }
    void printList(list<int> &v)
    {
    	for (list<int>::iterator it = v.begin(); it != v.end(); it++)
    	{
    		cout << *it << "\t";
    	}
    }
    
    int increase(int i)
    {
    	return i + 100;
    }
    
    void main42()
    {
    	vector<int> v1;
    	v1.push_back(1);
    	v1.push_back(3);
    	v1.push_back(5);
    	printV(v1);
    	cout << endl;
    	//使用回调函数
    	transform(v1.begin(), v1.end(), v1.begin(), increase);
    	printV(v1);
    	cout << endl;
    	
    	//使用预定义的函数对象
    	transform(v1.begin(), v1.end(), v1.begin(), negate<int>());
    	printV(v1);
    	cout << endl;
    
    	//使用函数适配器
    	list<int> mylist;
    	mylist.resize(v1.size());
    	transform(v1.begin(), v1.end(), mylist.begin(),bind2nd(multiplies<int>(),10));
    	printList(mylist);
    	cout << endl;
    
    	//把运算结果直接输出到屏幕
    	transform(v1.begin(), v1.end(), ostream_iterator<int>(cout, "\t"), negate<int>());
    
    }
    void main()
    {
    	main42();
    	cout << endl;
    	system("pause");
    }

     

  4.   for_each与transform的区别   一般情况下,for_each所使用的函数对象,参数是引用,没有返回值;tranform所使用的函数对象,参数一般不使用引用,而且还有返回值;
  5.  
  6.    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值