参见百度百科

一、给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中
申请512M的内存
一个bit位代表一个unsigned int值
读入40亿个数,设置相应的bit位
读入要查询的数,查看相应bit位是否为1,为1表示存在,为0表示不存在
二、使用位图法判断整形数组是否存在重复
判断集合中存在重复是常见编程任务之一,当集合中数据量比较大时我们通常希望少进行几次扫描,这时双重循环法就不可取了。
位图法比较适合于这种情况,它的做法是按照集合中最大元素max创建一个长度为max+1的新数组,然后再次扫描原数组,遇到几就给新数组的第几位置上1,如遇到 5就给新数组的第六个元素置1,这样下次再遇到5想置位时发现新数组的第六个元素已经是1了,这说明这次的数据肯定和以前的数据存在着重复。这种给新数组初始化时置零其后置一的做法类似于位图的处理方法故称位图法。它的运算次数最坏的情况为2N。如果已知数组的最大值即能事先给新数组定长的话效率还能提高一倍。
示例代码如下:
package com.sitinspring;
public class DuplicatedArrayTest {
public static void main(String[] args) {
int [][] arr = {
{ 1 , 2 , 3 , 5 , 3 , 5 , 56, 534 , 3 , 32 } ,
{ 1 , 2 , 3 , 5 } ,
{ 1 , 2 , 3 , 5 , 3 , 5 } ,
{ 0 , 0 , 1 , 2 , 3 , 5 , 56, 534 , 78 , 32 } ,
} ;
for ( int i = 0 ;i <arr.length;i ++ ) {
System.out.print( " 数组: " );
for ( int temp:arr[i]) {
System.out.print(temp + ", " );
}
System.out.print( " 中 " );
System.out.print(hasDuplicatedItem(arr[i]) ? " 存在 " : " 不存在 " );
System.out.print( " 重复元素.\n ");
}
}
/**
* 判断整形数组中是否有重复数据,时间复杂度为O(n)
* @param arr
* @return
*/
public static boolean hasDuplicatedItem( int [] arr) {
// 扫描数组找最大值
int max = arr[ 0 ];
for ( int i = 1 ;i <arr.length;i ++ ) {
if (arr[i] > max) {
max = arr[i];
}
}
// 按最大值创建一个新数组
int [] bitArray = new int [max +1 ];
// 按值向新数组中添值,如value为3则bitArray[3]=1
for ( int value:arr) {
if (bitArray[value] != 0 ) {
// 如果value指向的位置已经不是零,说明之前已经给这一块置1了,立即返回true表示数组有重复
return true ;
}
else {
// value指向的位置是零,则置为1表示这一位已经有数存在了
bitArray[value] = 1 ;
}
}
return false ;
}
}
输出:
数组: 1 , 2 , 3 , 5 , 3 , 5 , 56 , 534 , 3 , 32 ,中存在重复元素.
数组: 1 , 2 , 3 , 5 ,中不存在重复元素.
数组: 1 , 2 , 3 , 5 , 3 , 5 ,中存在重复元素.
数组: 0 , 0 , 1 , 2 , 3 , 5 , 56 , 534 , 78 , 32 ,中存在重复元素.
三、使用位图法进行整形数组排序
package com.heyang;
public class BitmapSorter {
public static void main(String[] args) {
int [] arr = { 1 , 7 , - 3 , 0 , 0 , 6 , 6 , 9 , - 11 } ;
bitmapSort(arr);
for ( int i:arr) {
System.out.print(i + " , " );
}
}
/**
* 使用位图法进行排序
* @param arr
*/
public static void bitmapSort( int [] arr) {
// 找出数组中最值
int max = arr[ 0 ];
int min = max;
for ( int i:arr) {
if (max < i) {
max = i;
}
if (min > i) {
min = i;
}
}
// 得到位图数组
int [] newArr = new int [max -min + 1 ];
for ( int i:arr) {
int index = i - min;
newArr[index] ++ ;
}
// 重整arr中的元素
int index = 0 ;
for ( int i = 0 ;i <newArr.length;i ++ ) {
while (newArr[i] > 0 ) {
arr[index] = i + min;
index ++ ;
newArr[i] -- ;
}
}
}
}
四、位图法存数据
在 8K 字节的内存空间内,如何存 unsigned short 类型数据?
一般做法:
定义一个数组: unsigned shortarrNormal[4096];
这样做,最多只能存 4K 个 unsigned short 数据。
利用位图法:
定义一个数组: unsigned chararrBit[8192];
这样做,能存 8K*8=64K 个 unsigned short 数据。
rrBit 存放的字节位置和位位置(字节 0~8191 ,位 0~7 )
比如写 1234 ,字节序: 1234/8 = 154; 位序: 1234 &0b111 = 2 ,那么 1234 放在 arrBit 的下标 154 字节处,把该字节的 2 号位( 0~7)置为 1
字节位置: int nBytePos =1234/8 = 154;
位位置: int nBitPos = 1234 & 7 = 2;
// 把数组的 154 字节的 2 位置为 1
unsigned short val = 1<<nBitPos;
arrBit[nBytePos] = arrBit[nBytePos] |val; // 写入 1234 得到arrBit[154]=0b00000100
此时再写入 1236 ,
字节位置: int nBytePos =1236/8 = 154;
位位置: int nBitPos = 1236 & 7 = 4
.// / 把数组的 154 字节的 4 位置为 1
val = 1<<nBitPos;
arrBit[nBytePos] = arrBit[nBytePos] |val; // 再写入 1236 得到arrBit[154]=0b00010100
读数据元素:按位读取 arrBit ,取得位为 1 的字节位置和位位置。元素值为 8*nBytePos + nBitPos
for (i=0; i<8192; i++)
{
for (j=0; j<8; j++)
{
if (arrBit[i] & (1<<j))
{
cout <<"arrBit:" << i << " " << j <<" " << 8*i+j <<endl;
}
}
}
会输出:
arrBit:154 2 1234
arrBit:154 4 1236
删除元素:计算待删除元素的字节位置和位位置:arrBit[nBytePos] &= ~(1<< nBitPos);
比如删除 1234 : arrBit[154] &= ~(1<<2);

位图 查找重复 排序 存数据相关推荐

  1. 教你用BitMap排序、查找和存储大量数据

    Bit-map的基本思想就是用一个bit位来标记某个元素对应的Value,而Key即是该元素.由于采用了Bit为单位来存储数据,因此在存储空间方面,可以大大节省. Bit-map概述 假设现在有这样一 ...

  2. 位图排序 大数据_干货分享:大话12种排序算法

    干货分享:大话12种排序算法 常见的排序算法: 快速排序.堆排序.归并排序.选择排序 插入排序.二分插入排序 冒泡排序.鸡尾酒排序 桶排序.计数排序.基数排序.位图排序 技能点: 1.归并排序在O(N ...

  3. oracle countif函数,字符串截取substr、excel表中查找重复数据countif

    1.字符串截取substr =left(a1,2)意思是取A1左面就是前面开始去2个字符 =right(a1,3)及时A1右面 就是走后面开始取3个字符 要是中间取 =mid(a1,2,4) 就是走A ...

  4. Oracle查找重复数据

    2019独角兽企业重金招聘Python工程师标准>>> -- 使用ROWID查找重复数据 -- PK_PSNDOC:查找该字段的重复数据值 -- LASTFLAG:条件过滤字段 SE ...

  5. 几百万的数据查找重复值_如何快速查找出Excel中的重复数据,多角度分析

    如何多角度查找出重复数据,是数据分析中必不可少的一项.办公中经常遇到重复数据,想要标识出来,再进一步分析,避免数据出错.像人事部门,经常遇到同名不同人这种情况,如果工资发错了,很容易出现大问题,如何来 ...

  6. Excel中两列数据对比,找出不同数据如何查找重复项并统计重复次数

    Excel中两列数据对比,找出不同数据 问题1 excel如何查找重复项并统计重复次数 问题2

  7. 【SQL】查找重复的数据

    @[查找重复的数据语句) 场景 使用PLSQL,查找ORACLE中从表中重复的外键id.主从表分开,主:从->1:多 语句意义 select id from tablename group by ...

  8. mysql 找表重复数据,mysql 数据表中查找重复记录

    mysql 数据表中查找重复记录 复制代码 代码如下: select user_name,count(*) as count from user_table group by user_name ha ...

  9. 怎么在excel中对比两列数据并查找重复项

    怎么在excel中对比两列数据并查找重复项 方法一: 方法二: 方法三: Excel查找2列相同的数据,并且返回对应列的另1列数据: IF函数语法格式: 方法一: =MATCH(A1,D$1:D95, ...

最新文章

  1. vlc的应用之十:vlc的远程控制
  2. boost::fusion::fold用法的测试程序
  3. iptables (2) 基本配置
  4. 大数据学习(0)-大数据知识框图
  5. Jsoup从一个文件加载一个文档
  6. 管理磁盘文件系统(三)
  7. NGINX实现负载均衡,并利用PHP实现session入库
  8. 我们为什么存在于三维空间而不是四维空间
  9. 解决Mac苹果旧电脑、更换过硬盘时升级10.13以上系统提示“验证估计时发生错误”导致无法升级、u盘重装、改时间、官方版本也不行的问题
  10. 基于just work的LE legacy pairing过程
  11. 尚硅谷maven视频教程笔记
  12. 【贪玩巴斯】带你一起攻克英语语法长难句—— 第二章——并列句全解 2021年12月17日——2022年2月5日
  13. 同样的代码不同环境 提示握手失败:ssl_client_socket_impl.cc handshake failed
  14. [系统安全] 二十一.PE数字签名之(中)Signcode、PEView、010Editor、Asn1View工具用法
  15. 联想计算机功耗,用起来又流畅又舒服功耗还低_联想ThinkCentre E95z(i3 7100U/4GB/500GB/集成)_一体电脑评测-中关村在线...
  16. 判定2000—2500年中的每一年是否为闰年,并将结果输出。
  17. 硬件设计36之什么是晶振?
  18. Spring Boot实战,整合Prometheus实现应用监控
  19. python常用框架
  20. 基于k近邻算法的干豆品种分类

热门文章

  1. libsigc++库的使用
  2. java输出gc_GC输出澄清
  3. 买卖股票 状态机模型的理解
  4. shell脚本中使用seq生成连续整数
  5. mysql 主机 %_MySQL 开启远程链接(localhost 以外的主机)
  6. c语言 memset 段错误,段错误之memset对类对象的误用
  7. php文本文件操作,PHP文本操作类
  8. fx-4500科学计算机用法,应用CASIOfx-4500PA计算器计算LC50的方法
  9. C语言实现易语言变量框,c语言实现简单的易语言
  10. wps分享为什么要登入_【知识点分享】钢筋上的螺纹有什么作用?为什么要有螺纹?...