[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源码剖析》
[STL]算法的泛化过程的更多相关文章
- 算法的泛化过程(摘自《STL源码剖析》)
将一个叙述完整的算法转化为程序代码,不是什么难事.然而,如何将算法独立与其所处理的数据结构之外,不受数据结构的羁绊呢?换个说法,如何将我们所写的程序算法适用于任何(或者大部分)未知的数据结构(比如ar ...
- STL——算法简介
一.算法概观 以有限的步骤,解决逻辑或数学上的问题,这一专门科目我们称为算法.特定的算法往往搭配特定的数据结构,例如binary search tree(二叉搜索树)和 RB-tree 便是为了解决查 ...
- 变易算法 - STL算法
欢迎访问我的新博客:http://www.milkcu.com/blog/ 原文地址:http://www.milkcu.com/blog/archives/mutating-algorithms.h ...
- STL非变易算法 - STL算法
欢迎访问我的新博客:http://www.milkcu.com/blog/ 原文地址:http://www.milkcu.com/blog/archives/1394600460.html 原创:ST ...
- C++ 11 STL算法
STL算法部分主要由头文件<algorithm>,<numeric>,<functional>组成.要使用 STL中的算法函数必须包含头文件<algorith ...
- STL算法分类记忆
STL算法主要是我们强大的标准库中以迭代器或数值或函数对象为参数预先定义好的一系列算法操作. 在STL算法分类中首先要提的就是两个普遍存在的后缀: _if _copy 其中这两个后缀的作用分别是:一. ...
- STL源代码剖析——STL算法stl_algo.h
前言 在前面的博文中剖析了STL的数值算法.基本算法和set集合算法.本文剖析STL其它的算法,比如排序算法.合并算法.查找算法等等.在剖析的时候.会针对函数给出一些样例说明函数的使用.源代码出自SG ...
- [转] Paxos算法2-算法过程(实现)
请先参考前文:Paxos算法1 1.编号处理 根据P2c ,proposer在提案前会先咨询acceptor查看其批准的最大的编号和value,再决定提交哪个value.之前我们一直强调更高编号的pr ...
- STL算法
STL算法部分主要由头文 件<algorithm>,<numeric>,<functional>组成.要使用 STL中的算法函数必须包含头文件<algorit ...
随机推荐
- linux terminal 日常shell
1 ubuntu中如何将终端添加到右键 /home/cui/.local/share/nautilus/scripts #!/bin/bash #cd $NAUTILUS_SCRIPT_CURRENT ...
- 转换 Html 内容为纯文本内容(html,文本互转)
转自http://www.cnblogs.com/jyshi/archive/2011/08/09/2132762.html : /// <summary> /// 转换纯文本内容为 HT ...
- c#配置log4net步骤
1.引入添加log4net.dll引用 2.建立配置文件Log4Net.config(名字自定义).文件内容参考,输出的文件名称可更改 .运行是要放入到相应bin/debug(release) 目录 ...
- 【Delphi】最小化事件捕捉
添加一个ApplicationEvents组件在窗体,然后处理其OnMinimize事件和OnRestore事件即可.
- How to using x++ creating Vendors [AX2012]
.//Create party for the vendor public void createParty(VendorRequestCreate _vendorRequestCreate) { ; ...
- JS面向对象编程创建类的方式
js创建类的方式有几种,大致如下: 1,构造函数方式: function Car(parameters) { this.name = "objectboy"; } var cat1 ...
- [转]system函数返回值探究
对于system这个函数的功能早就有一定了解,读书期间,就学习了UNIX系统编程这本书,后来买了APUE.我这个人总是有好读书不求甚解的毛病.对于system函数只知其一,不知其二.后来被人问起相关的 ...
- java抽象类和接口详解
接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法. 抽象类与接口是java语言中对抽象概念进行定义的两种机制,正是由于他们的存在才赋予java强大的面向对象的能力.他们两者之间对抽象概念 ...
- 为什么C/C++语言使用指针
这是参加面试时,面试官问的一道开放性题目. 问题是:为什么C/C++语言使用指针? 这个问题一问出来,直接被面试官秒杀了,面试官大神,你怎么不按套路出牌啊? 说好的malloc和new的区别呢?说好的 ...
- ASP.NET操作WMI
WMI Functions from ASP.NET Introduction This article demonstrates how to use WMI in ASP.NET to cre ...