您的位置:首页 > 其它

稀疏数据压缩查询方法:Rank & Select 操作

2014-06-14 11:28 295 查看
1.稀疏数据的例子

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

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

2.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,0,sizeof(int)*n);
num[1] = 12;    *ver_A |= (1<<1);
num[3] = 2;     *ver_A |= (1<<3);
num[5] = 23;    *ver_A |= (1<<5);
num[8] = 11;    *ver_A |= (1<<8);
num[9] = 12;    *ver_A |= (1<<9);
num[13] = 1;    *ver_A |= (1<<13);
return 0;
}

/**
ver_A:位向量
rank:排名
num_B:压缩后的数组
pos:要查的位置
*/
int query(int *ver_A,int *rank,int *num_B,int pos){
if((*ver_A&(1<<pos)) == 0)
return 0;
else
return num_B[rank[pos]];
}

int main (){
const int n = 14;
int  ver_A = 0;
int *num = new int
;
int *rank = new int
;
int *num_B = new int[7];    ///例子中有效数字6个,num_B[0]不使用

///设置原始数组num以及设置对应在ver_A的比特位
initNumVer(num,&ver_A,14);

///设置rank与压缩后的数组num_B
for(int i=0,j=0;i<n;i++){
if( (ver_A&(1<<i)) != 0)
num_B[++j] = num[i];
rank[i]=j;
}

///查询第4、5个数
cout<<"第4个数:"<<query(&ver_A,rank,num_B,4)<<endl;
cout<<"第5个数:"<<query(&ver_A,rank,num_B,5)<<endl;

delete [] num;
delete [] rank;
delete [] num_B;
return 0;
}


View Code
[b]6.注意


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

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

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

本文连接:/article/4814003.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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐