• [STL]算法的泛化过程


    选择了错误的算法,便注定了失败的命运”。最近对这句话感触颇深,经常因为一开始思路错误,修改半天,到头来却都是无用功,所以学好算法势在必行。

    算法的泛化过程

    如何设计一个算法,使他适用于任何(大多数)数据结构呢?先看一个算法泛华的实例。

    假设我们要写一个find()函数,在array中寻找特定值。面对整数array,我们很快能写出:

    int *find(int *array,int size,int target)
    {
    	for(int i=0;i<size;i++)
    	{
    		if(array[i]==target)
    			break;
    	}
    	return &(array[i]);
    }
    

    该函数在某个区间内寻找target。返回的是一个指针,只想它所找到的第一个符合条件的元素;如果没有找到,就返回最后一个元素的下一个地址。“最后一个元素的下一个地址”称为end。返回end就表示查找无结果。

    现在可以这样使用find()函数:

    const int size=7;
    int array[size]={0,1,2,3,4,5,6};
    int *end=array+size; //最后一个元素位置
    int *ans=find(array,sizeof(array)/sizeof(int),4);
    if(ans==end) cout<<"4 not found"<<endl;
    else cout<<"4 found。 "<<*ans<<endl;
    

    但是,find()暴露了容器太多的实现细节,也因此太依附于容器。为了让find()试用于所有类型的容器,其操作应该更抽象化。让find()接受两个指针作为参数,标出一个操作区间:

    int *find(int *begin,int *end,int value)
    {
    	while(begin!=end&&*begin!=value)
    		begin++;
    	return begin;
    }
    

    由于find()函数之内并无任何操作时针对特定的整数array,所以我们可以将它改为一个template:

    template<class T>
    T *find(T *begin,T *end,T& value)
    {	
    	while(begin!=end&&*begin!=value)
    		begin++;
    	return begin;
    }
    

    这样的find()几乎适用于任何容器。但对于list呢?还是不够。

    在C++中,上述操作符或操作行为都可以被重载。如果我们以一个原生指针指向某个list,则对该指针进行“++”操作并不能指向下一个串行节点,但如果哦我们设计一个class,拥有原生指针的行为,并使其”++“操作指向list的下一个节点,那么find()就可以施行于list容器上了。这便是迭代器(iterator)的观念。迭代器是一种行为类似指针的对象,下面将find()函数内的指针以迭代器取代:

    template<class Iterator,class T>
    Iterator *find(Iterator *begin,Iterator *end,const T& value)
    {
    	while(begin!=end&&*begin!=value)
    		begin++;
    	return begin;
    }
    

    这便是一个完全泛型化的find()函数,有了这样的观念,再看STL的各式各样的泛型算法,就轻松多了。

    参考:《STL源码剖析》

  • 相关阅读:
    js数组去重
    js和jq实现全选反选
    js的作用域深入理解
    js对数组的常用操作
    如何写出让java虚拟机发生内存溢出异常OutOfMemoryError的代码
    JAVA编程思想(第四版)学习笔记----4.8 switch(知识点已更新)
    通过拦截器Interceptor实现Spring MVC中Controller接口访问信息的记录
    JAVA编程思想(第四版)学习笔记----11.10 Map
    JAVA中的for-each循环与迭代
    JAVA编程思想(第四版)学习笔记----11.5 List,11.6迭代器
  • 原文地址:https://www.cnblogs.com/Rosanna/p/3457999.html
Copyright © 2020-2023  润新知