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

算法的泛化过程

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

假设我们要写一个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. DataGrid3

    a标签,DataGrid的数据绑定 1.function aa(id, url) {            //alert(id);            window.open(url + '&am ...

  2. win8系统下保存出现闪退的解决方案

    不知道有没有人和我一样用的是win8系统,同时还遇到保存QQ截图保存闪退.保存sublime文件闪推.系统自带截图保存闪退.....更可恶的是我用chrome中百度搜索“win8保存东西闪退”结果浏览 ...

  3. Mvc中把list从View传入Controller

    public class User { public string Name { get; set; } public bool IsChecked { get;set;} public int Ag ...

  4. C# 发邮件类可发送附件

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Ne ...

  5. VirtualBox虚拟机安装MSDOS和MINIX2.0.0双系统

    1. 在VirtualBox中新建一个MSDOS虚拟机. 2.下载一个MSDOS软盘镜像. 3.启动虚拟机,提示选择安装盘时,选择步骤2下载过来的MSDOS镜像. 4.正常启动进入DOS命令行,用FD ...

  6. 暂停更新Blog

    今天非常不好意思的是老魏又要一次的暂停文章跟新了,原因是有些有问题老魏需要从新的梳理,加上这几天工作又开始忙碌起来了,所以这一阵子估计很难有有时间更新了. 不过老魏会抽一下时间更新文章的,不可能像2月 ...

  7. sharepoint mysite and upgrade topics

    My Sites overview (SharePoint Server 2010)http://technet.microsoft.com/en-us/library/ff382643(v=offi ...

  8. win7 telnet命令无法使用

    很多做网络测试的同学发现安装win7后,无法使用telnet命令了,提示“telnet不是内部或外部命令,也不是可运行的程序”,但是很需要在win7中使用telnet工具,怎么办? 首先你要要确认你的 ...

  9. Luence简单实现2

    上一篇是基于内存存储的,这次的例子是基于本地存储索引库. 上一次的代码稍微修改,代码如下: //创建词法分析器 Analyzer analyzer = new StandardAnalyzer(); ...

  10. Python编程规范

    打破一条既定规则的两个理由: 应用这个规则将导致代码可读性下降. 为了和周围的代码保持一致. 编码: 所有的 Python 脚本文件都应在文件头标上如下标识或其兼容格式的标识: # -*- codin ...