[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 ...
随机推荐
- java大数--总结
BigInteger(高精度整数) 1.所在包: java.math.BigInteger 2.大数运算,以下返回类型均为BigInteger BigInteger a; BigInteger b; ...
- silverlight 用户浏览器未安装SL插件问题
1.在Silverlight启动页面 <%@ Page Language="C#" AutoEventWireup="true" %> <!D ...
- Discuz 3.X 门户文章插入图片自动添加 alt 标签
最近用 Discuz 搭建了个网站--儿童安全座椅网(www.bbseat.com.cn),用到了门户功能,不得不说Discuz 的功能还是非常强大的,但在使用过程中发现在发表文章时添加了图片却不能像 ...
- 忘记linux root密码怎么办?
摘自:<鸟哥的Linux私房菜> 常常有些朋友在配置好了Linux之后,结果root密码给他忘记去!要重新安装吗?不需要的, 你只要以单人维护模式登陆即可更改你的root密码喔!由于lil ...
- SQL随机数的生成
下面是一个随机函数问题,获取两位数的随机数,且不重复. 但是说明一下,这个函数有点bug,例如:两位数的函数最后能生成89个,如果将数量改成90,那么就无法生成,陷入死循环了. IF object_i ...
- c++继承详解
C++中的三种继承public,protected,private 三种访问权限 public:可以被任意实体访问 protected:只允许子类及本类的成员函数访问 private:只允许本类的成员 ...
- MySQL Online DDL 工具之pt-online-schema-change
MySQL DDL:DDL是一个令所有MySQL dDBA 诟病的一个功能,因为在MySQL中在对表进行dDDL时,会锁表,当表比较小比如小于1W行时,对前端影响较小,当时遇到千万级别的表,就会影响前 ...
- 在IOS中使用json
1.从https://github.com/stig/json-framework/中下载json框架:json-framework 2.解压下载的包,将class文件夹下的所有文件导入到当前工程下. ...
- Build Settings
Add Open Scenes 选择一个关卡,使其处于打开状态,在菜单栏选择 File -> Build Settings 打开Build Settings窗口.选择 Add Open Scen ...
- 在wamp下PHP5.5安装php-redis扩展
windows下开发用的xampp集成的环境,想装个php-redis扩展,扩展的github地址: https://github.com/nicolasff/phpredis 描述里找到window ...