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

算法的泛化过程

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

假设我们要写一个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源码剖析》

[STL]算法的泛化过程的更多相关文章

  1. 算法的泛化过程(摘自《STL源码剖析》)

    将一个叙述完整的算法转化为程序代码,不是什么难事.然而,如何将算法独立与其所处理的数据结构之外,不受数据结构的羁绊呢?换个说法,如何将我们所写的程序算法适用于任何(或者大部分)未知的数据结构(比如ar ...

  2. STL——算法简介

    一.算法概观 以有限的步骤,解决逻辑或数学上的问题,这一专门科目我们称为算法.特定的算法往往搭配特定的数据结构,例如binary search tree(二叉搜索树)和 RB-tree 便是为了解决查 ...

  3. 变易算法 - STL算法

    欢迎访问我的新博客:http://www.milkcu.com/blog/ 原文地址:http://www.milkcu.com/blog/archives/mutating-algorithms.h ...

  4. STL非变易算法 - STL算法

    欢迎访问我的新博客:http://www.milkcu.com/blog/ 原文地址:http://www.milkcu.com/blog/archives/1394600460.html 原创:ST ...

  5. C++ 11 STL算法

    STL算法部分主要由头文件<algorithm>,<numeric>,<functional>组成.要使用 STL中的算法函数必须包含头文件<algorith ...

  6. STL算法分类记忆

    STL算法主要是我们强大的标准库中以迭代器或数值或函数对象为参数预先定义好的一系列算法操作. 在STL算法分类中首先要提的就是两个普遍存在的后缀: _if _copy 其中这两个后缀的作用分别是:一. ...

  7. STL源代码剖析——STL算法stl_algo.h

    前言 在前面的博文中剖析了STL的数值算法.基本算法和set集合算法.本文剖析STL其它的算法,比如排序算法.合并算法.查找算法等等.在剖析的时候.会针对函数给出一些样例说明函数的使用.源代码出自SG ...

  8. [转] Paxos算法2-算法过程(实现)

    请先参考前文:Paxos算法1 1.编号处理 根据P2c ,proposer在提案前会先咨询acceptor查看其批准的最大的编号和value,再决定提交哪个value.之前我们一直强调更高编号的pr ...

  9. STL算法

    STL算法部分主要由头文 件<algorithm>,<numeric>,<functional>组成.要使用 STL中的算法函数必须包含头文件<algorit ...

随机推荐

  1. 杭电ACM2085--核反应堆

    http://acm.hdu.edu.cn/showproblem.php?pid=2085 这也是一个简单的的递推. a[i][0] = 3*a[i-1][0]+2*a[i-1][1]; a[i][ ...

  2. 杭电ACM2058--The sum problem

    http://acm.hdu.edu.cn/showproblem.php?pid=2058 以为简单的穷举就完了,结果是一直Time Limit Exceeded.. 这是代码: #include ...

  3. c/c++面试总结(2)

    4.深拷贝和浅拷贝 (1)什么时候会用到拷贝函数 一个对象以值传递的方式传入函数(就是作为入参) 一个对象以值传递的方式从函数返回(就是作为返回值) 一个对象需要通过另外一个对象进行初始化 (2)是否 ...

  4. 【风马一族_Python】 安装pip与Numpy

    ------------------------------------------------------------------------------------------------- 原因 ...

  5. linux远程客户端putty,xshell搭建注意事项——《视频》

    本视频放在云端,点击此链接即可播放:              http://www.tudou.com/programs/view/75QMh0-DQfA/               崇尚开源,热 ...

  6. Bootstrap Paginator 分页 demo.

    效果如下: 需要的引用以下内容 bootstrap2 http://cnbootstrap.com/ bootstrap-paginator v0.5 主页 http://bootstrappagin ...

  7. header页头内容整理

    meta标签 <meta charset="UTF-8"/> <!--视窗宽度--> <meta name="viewport" ...

  8. windows程序消息机制(Winform界面更新有关)

    windows程序消息机制(Winform界面更新有关) 转自:http://www.cnblogs.com/blosaa/archive/2013/05/31/3109586.html 1. Win ...

  9. PHP:parse_str()字符串函数

    parse_str()-把字符串解析成多个变量. 描述:void parse_str(sring $str  [, array $arr]) 如果str是URL传递入的查询字符串(query stri ...

  10. ASP.NET——拒绝访问。 (异常来自HRESULT:0x80070005 (E_ACCESSDENIED))

    运行ASP.NET网站的时候出现下面这个问题,这个问题如图: 这个问题的解决方法为: 运行dcomcnfg 点 组件服务->服务->电脑->我的电脑->DCOM 配置 找到&q ...