1.稀疏数据的例子

  对于网络图对应的节点关联矩阵、数据生成的哈希表等,这些存储起来是稀疏的,这样我们就会想到需要压缩空间。但是在压缩存储空间的同时,还要支持高效的查询操作。

  Rank & Select 就可以对稀疏的数据进行压缩,还能支持高效的查询操作。

2.Rank & Select 操作压缩稀疏数据原理

  以下图为例子,假如是经过哈希后得到的哈希数组:

  

  构造数组A和B:

    Vec-A:1010100110001    (每个位置一个比特位,1:有数据,0:无数据)

     Num-B:12  2  23  11  12  1  (数据按原来的相对顺序,保存为一个数组)

  (1)Rank:

    针对Vec-A数组而言,记录每个位置前面(包括本位)有多少个1,也就是对应之前有多少个有效数字。这样做的目的是使得,数组中的有效数字的排名与在Num-B中的位置一致。

  (2)Select:

    根据查询数据在Vec-A上面的Rank排名,在Num-B中查询数据。

  (3)Rank & Select

    

    eg1:位置4对应的位置没有数据,所以在Vec-A中标记为0;

    eg2:位置5对应的位置有数据23,所以在Vec-A中标记为1。Vec-A(5)对应的rank为3,说明包含自己在内之前一共有3个数据,且在位置5对应的数据保存在Num-B的第3为,即Select(5)=Num-B(Rank(5))

4.使用SSE指令高效计算Rank

  SIMD,单指令多数据,就是一条指令由多个执行单元同时并行执行操作多个数据。

  SSE是指令集的简称,它包括70条指令,其中包含SIMD浮点计算、以及额外的SIMD整数和高速缓存控制指令。就是说SSE中存在指令,是SIMD指令,使得多核CPU可以高效执行。

  SSE指令 int _mm_popcnt_u32 (unsigned int a); 返回32为无符号整形 a 中bit位为1的位的个数。

5.Rank & Select 简单示例

  实例程序就是上面图中的例子,13个位置(1,2,3,..,14),6个有效位置。对其进行使用rank & select,进行压缩、并支持查询。

  例子较小,没有使用SSE指令,只是对rank select操作的简单说明。

 #include <iostream>
#include <string.h>
#include <bitset>
using namespace std; /**
设置原始数组num以及设置对应在ver_A的比特位
num:保存原始数据的数组
n:数组大小
ver_A:标记有效数字位向量
*/
int initNumVer(int *num,int *ver_A,int n){
memset(num,,sizeof(int)*n);
num[] = ; *ver_A |= (<<);
num[] = ; *ver_A |= (<<);
num[] = ; *ver_A |= (<<);
num[] = ; *ver_A |= (<<);
num[] = ; *ver_A |= (<<);
num[] = ; *ver_A |= (<<);
return ;
} /**
ver_A:位向量
rank:排名
num_B:压缩后的数组
pos:要查的位置
*/
int query(int *ver_A,int *rank,int *num_B,int pos){
if((*ver_A&(<<pos)) == )
return ;
else
return num_B[rank[pos]];
} int main (){
const int n = ;
int ver_A = ;
int *num = new int[n];
int *rank = new int[n];
int *num_B = new int[]; ///例子中有效数字6个,num_B[0]不使用 ///设置原始数组num以及设置对应在ver_A的比特位
initNumVer(num,&ver_A,); ///设置rank与压缩后的数组num_B
for(int i=,j=;i<n;i++){
if( (ver_A&(<<i)) != )
num_B[++j] = num[i];
rank[i]=j;
} ///查询第4、5个数
cout<<"第4个数:"<<query(&ver_A,rank,num_B,)<<endl;
cout<<"第5个数:"<<query(&ver_A,rank,num_B,)<<endl; delete [] num;
delete [] rank;
delete [] num_B;
return ;
}

6.注意

  (1)程序中以一维数组为例,其实多维数组也是连续存储,也可以理解为“一维数组”。

  (2)SSE指令时间复杂度为O(1),但是SSE指令操作位数有限。

  (3)如果Vec-A比特向量很长时,可以先计算一些rank数据保存下来(空间换时间),也可以达到计算任意位置rank操作时间复杂度为O(1)。

本文连接:http://www.cnblogs.com/xudong-bupt/p/3787658.html

参考链接:

SIMD : http://en.wikipedia.org/wiki/SIMD

_mm_popcnt_u32: http://msdn.microsoft.com/zh-cn/library/bb514083.aspx

SSE: http://en.wikipedia.org/wiki/SSE5

稀疏数据压缩查询方法:Rank & Select 操作的更多相关文章

  1. thinkphp数据查询方法总结select ,find,getField,query

    thinkphp已经封装好了常用的查询方法,且都比较实用,对于不常用的查询框架也保留了原始查询方法query. 1 2 $Model = new Model() // 实例化一个model对象 没有对 ...

  2. ThinkPHP 数据库操作(三) : 查询方法、查询语法、链式操作

    查询方法 条件查询方法 where 方法 可以使用 where 方法进行 AND 条件查询: Db::table('think_user') ->where('name','like','%th ...

  3. MyBaits一对一的查询方法

    MyBaits一对一的查询方法 一:表数据与表结构 CREATE TABLE teacher( t_id INT PRIMARY KEY AUTO_INCREMENT, t_name ) ); CRE ...

  4. 使用ResultSet,写了一个通用的查询方法

    此方法很烂,以后优化 /** * 通用的查询方法:SELECT */ @SuppressWarnings({ "unchecked", "rawtypes" } ...

  5. SpringBoot05 数据操作03 -> JPA查询方法的规则定义

    请参见<springboot详解>springjpa部分知识 1 按照方法命名来进行查询 待更新... package cn.xiangxu.springboot.repository; ...

  6. Thinkphp中的volist标签(查询数据集(select方法)的结果输出)用法简介

    参考网址:http://camnpr.com/archives/1515.html 通常volist标签多用于查询数据集(select方法)的结果输出,通常模型的select方法返回的结果是一个二维数 ...

  7. 【Java EE 学习 17 下】【数据库导出到Excel】【多条件查询方法】

    一.导出到Excel 1.使用DatabaseMetaData分析数据库的数据结构和相关信息. (1)测试得到所有数据库名: private static DataSource ds=DataSour ...

  8. Thinkphp回顾之(四)查询方法深入学习

    本次讲的查询方法主要有:表达式查询,模糊查询,between语句,in语句,区间查询,统计数据,普通方式查询,但大多数都只是引入数组而已,明白了第一个,其他的也就差不多全明白了,唯一要注意的是在后台中 ...

  9. JAVA 模糊查询方法

    当我们需要开发一个方法用来查询数据库的时候,往往会遇到这样一个问题:就是不知道用户到底会输入什么条件,那么怎么样处理sql语句才能让我们开发的方法不管接受到什么样的条件都可以正常工作呢?这时where ...

随机推荐

  1. 2017-2018-1 20179202《Linux内核原理与分析》第七周作业

    一 .Linux内核创建一个新进程的过程 1. 知识准备 操作系统内核三大功能是进程管理,内存管理,文件系统,最核心的是进程管理 linux 进程的状态和操作系统原理的描述进程状态有所不同,比如就绪状 ...

  2. mysql插入数据时,去掉重复的数据;

    1. 利用insert ignore into语句去重 mysql> INSERT IGNORE INTO person_tbl (last_name, first_name) -> VA ...

  3. 使用VisualStudio2015开发QT项目

    一直习惯用VS,做QT项目时,不停的来回切IDE有些不方便.研究了一下QT的编译. 实际QT编译的机制和cmake是相同的,QT的IDE使用pro文件进行项目管理.QMake通过解析pro工程文件,生 ...

  4. FPGA+ARM or FPGA+DSP?

    网上有人说.现在的FPGA,ARM功能已经强大到无需DSP协助处理了,未来DSP会不会消声灭迹?是DSP取代FPGA和ARM,还是ARM,FPGA取代DSP呢?担心好不容易学精了DSP,结果DSP变成 ...

  5. List元素为泛型时的注意事项

    最近的项目赶得非常紧,这节奏跟最近的天气一点也不搭调. 编码的过程,遇到一个关于List的小问题. 在调用List.add(E e)的时候范了一个小毛病,很自然地认为list中存储的是 E  对象的另 ...

  6. [ 转载 ] Java开发中的23种设计模式详解(转)

    Java开发中的23种设计模式详解(转)   设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类 ...

  7. 机器学习之路:python 集成分类器 随机森林分类RandomForestClassifier 梯度提升决策树分类GradientBoostingClassifier 预测泰坦尼克号幸存者

    python3 学习使用随机森林分类器 梯度提升决策树分类 的api,并将他们和单一决策树预测结果做出对比 附上我的git,欢迎大家来参考我其他分类器的代码: https://github.com/l ...

  8. MSSQL 基础知识与语句笔记

    建库 CREATE DATABASE 数据库名 ON[PRIMARY] --默认属于PRIMARY主文件组,可省略 ( NAME='', --主数据文件的逻辑名 名称 FILEAME='', --主数 ...

  9. [CSAcademy]Cycle Tree

    [CSAcademy]Cycle Tree 题目大意: 定义环树是一张无向连通的简单图,它的生成方式如下: \(2\)个点\(1\)条边的图是环树: 对任意一个环树,加入\(k\)个点\(a_{1\s ...

  10. Codeforces Round #350 (Div. 2) E. Correct Bracket Sequence Editor 栈 链表

    E. Correct Bracket Sequence Editor 题目连接: http://www.codeforces.com/contest/670/problem/E Description ...