Fractional Cascading算法是用于将零散的多个数组(亦可理解成比较高维的空间)中的数据的二分查找速度增加,用的是空间换时间的方法。然而这种方法并不是很好懂,而且中文文献很少。在这里介绍一种简单的伪Fractional Cascading算法。其实它与Fractional Cascading并没有任何关系,这里提到只是借个名声罢了。

  假设这些数据是二维的。即:有k个一维数组,其中一共存储了n个元素。要实现快速查找的目的,一般都会先进行排序,然后每次对于每个数组进行二分查找。时间复杂度为。考虑极限情况,即k=n时,显然,时间复杂度会退化到,显然不是一个好办法。

  现在就要谈我们的“伪Fractional Cascading”了。我们可以按照类似的思想,以空间换时间,建立一个大数组存储所有的键值对,顺带坐标信息。搜索时只需在这个大数组内进行,时间复杂度稳定为,且无退化情况。

  顺便我做了一个实际时间的对比表,结果如下(在Win10下,CPU:E3 1230V2,g++5.1.0编译,编译优化开关“-O3”,表中n,k如上文所述,查询重复times次):

# n k times 朴素二分查找(ms) 伪Fractional Cascading(ms)
1 1000000 200 10000 163 9
2 1000000 20000 10000 5763 8
3 10000000 200 10000 311 13
4 10000000 20000 10000 14433 20

  对比1,2与3,4可以明显看出,朴素二分查找的速度与k即数组的个数的关系很大。所以在k大的时候,伪Fractional Cascading更能发挥出优势。

  对比1,3与2,4可以明显看出,朴素二分查找的速度受n的影响也是随着k的增大而增大的。

  现在讲讲实现。STL很好的支持了数据检索这个需求,在朴素二分查找中可以直接使用binary_search函数查找。但是在伪Fractional Cascading算法中,不仅要保存值,还要保存坐标,这时候使用关联容器map系列更加方便。然而,在这个测试中同一个随机数可能分布在多个数组内,所以我还是用了multi_map。测试时间的样例程序可以在这里下载:FakeFractionalCascading.cpp(使用了一些c++11特性,编译时请加上相应的编译开关)

Updated 2015-12-5 18:11:

  这里把文下的一个评论提前:“@Antineutrino忘了在文章里写了,其实这就是为什么称为“伪Fractional Cascading”的原因。Fractional Cascading使用树结构,插入删除后调整也是对数级别的复杂度。然而像你所看到的,这个伪算法显然不能满足这个需求,所以就称它为离线结构吧。虽然 离线结构看起来没有什么意义,但是在一次性查询次数与修改次数差距悬殊时,对于程序的效率提升还是很明显的。”

  是的,这个结构有一个致命的弱点就是不支持动态修改(或者说很慢)。

简单快速的伪Fractional Cascading的更多相关文章

  1. CocoaPods 的简单快速安装方法

    CocoaPods 的简单快速安装方法(Setting up CocoaPods master repo 卡着不动,是因为淘宝镜像已经不能用了. 一.git clone方法安装cocoapods 镜像 ...

  2. 【转】让你10分钟搞定Mac--最简单快速的虚拟安装

    文章出处:让你10分钟搞定Mac--最简单快速的虚拟安装http://bbs.itheima.com/thread-106643-1-1.html (出处: 黑马程序员训练营论坛) 首先说明一下. 第 ...

  3. PlantUML —— 应用于 Eclipse 的简单快速的 UML 编辑软件

    PlantUML —— 应用于 Eclipse 的简单快速的 UML 编辑软件 简介: 在应用系统软件开发过程中,如果软件由很多对象组成,它的结构仅仅凭借分析很难理清,同时为了有利于软件的开发及重用, ...

  4. 一种简单快速的模板解析方法,活用with javascript版

    //一种简单快速的模板解析方法,活用with var parseTpl = function( str, data ) { var tmpl = 'var __p=[];' + 'with(obj|| ...

  5. Mario是一个基于.NETCore的简单快速开发框架

    Mario .NET Core简单快速开发框架 Mario是一个基于.NET Core的简单快速开发框架 GitHub:https://github.com/deeround/Mario 技术特点 基 ...

  6. 简单快速搭建钓鱼wifi

    前言 钓鱼wifi是很久的话题了,但是传统的方法可能比较麻烦需要手动配置dhcp,dns,网卡,流量转发,比较麻烦,而且还有根据每次的网络环境需要重新的配置,这里介绍用WIFIpumpkin3工具简单 ...

  7. 简单快速安装Apache+PHP+MySql服务环境(四)—— 将php版本升级到7.2

    书接上文,简单快速安装Apache+PHP+MySql服务环境(二)-- centos使用yum安装指定版本的php. 随着各种PHP框架的升级,对PHP的版本也有了更高的要求,所以笔者也尝试着更新升 ...

  8. 简单快速的开发框架-SRF

    1.是什么 SRF(simply and rapid development framework) 一套基于asp.net mvc的开发框架,致力于提供简单.快速的企业应用开发方案,旨在解决企业应用开 ...

  9. iOS简单快速集成Cordova

    如果你对于什么是Cordova还不了解,可以先移步到我另一个文章:Cordoval在iOS中的运用整理 里面有详细的介绍跟如何搭建Cordova:而本文则是要介绍JiaCordova插件,如果你有一点 ...

随机推荐

  1. ASP.NET MVC 3 入门级常用设置、技巧和报错

    1.ASP.NET MVC 3 如何去除默认验证 这个默认验证是在web.config配置文件中设置的    <add key="ClientValidationEnabled&quo ...

  2. 用scikit-learn实现朴素贝叶斯分类器 转

    原文:http://segmentfault.com/a/1190000002472791 朴素贝叶斯(Naive Bayes Classifier)是一种「天真」的算法(假定所有特征发生概率是独立的 ...

  3. PHP中::、->、self、parent::、$this操作符的区别

    在访问PHP类中的成员变量或方法时,如果被引用的变量或者方法被声明成const(定义常量)或者static(声明静态),那么就必须使用操作符::,反之如果被引用的变量或者方法没有被声明成const或者 ...

  4. [Java] 集合类(List、Set、Map的基本使用)

    数组是一种很常见的数据结构,开始接触编程的时候多数程序都和数组相关.刚开始接触Java时也是一直使用数组写一些程序,后来越来越觉得... 数组是一种很常见的数据结构,开始接触编程的时候多数程序都和数组 ...

  5. Android 高级UI设计笔记03:使用ListView实现左右滑动删除Item

    1. 这里就是实现一个很简单的功能,使用ListView实现左右滑动删除Item: (1)当我们在ListView的某个Item,向左滑动显示一个删除按钮,用户点击按钮,即可以删除该项item,并且有 ...

  6. struts2.1笔记02:servlet简介

    1.     Servlet 是在服务器上运行的小程序.这个词是在 Java applet的环境中创造的,Java applet 是一种当作单独文件跟网页一起发送的小程序,它通常用于在客户端运行,结果 ...

  7. javascript 通过面向对象编写圆形数字时钟

    效果如图所示,代码如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...

  8. NSURLConnection、NSURLSession

    NSURLConnection   1.准备网络资源地址:URL 注意:由于URL支持26个英文字母,数字和少数的几个特殊字符. 因此对于URL中包含非标准URL的字符,需要进行编码. iOS提供了函 ...

  9. Java垃圾回收(GC)与引用的种类

    垃圾回收 GC public class MyObject {     private String id;     public MyObject(String id) {         this ...

  10. 用java 删除mongodb的数据

    import java.net.UnknownHostException; import com.mongodb.BasicDBObject;import com.mongodb.DB;import ...