经典算法题每日演练——第十一题 Bitmap算法 (转)
2017-12-04 10:33
309 查看
http://www.cnblogs.com/huangxincheng/archive/2012/12/06/2804756.html
在所有具有性能优化的数据结构中,我想大家使用最多的就是hash表,是的,在具有定位查找上具有O(1)的常量时间,多么的简洁优美,
但是在特定的场合下:
①:对10亿个不重复的整数进行排序。
②:找出10亿个数字中重复的数字。
当然我只有普通的服务器,就算2G的内存吧,在这种场景下,我们该如何更好的挑选数据结构和算法呢?
一:问题分析
这年头,大牛们写的排序算法也就那么几个,首先我们算下放在内存中要多少G: (10亿 * 32)/(1024*1024*1024*8)=3.6G,可怜
的2G内存直接爆掉,所以各种神马的数据结构都玩不起来了,当然使用外排序还是可以解决问题的,由于要走IO所以暂时剔除,因为我们
要玩高性能,无望后我们想想可不可以在二进制位上做些手脚?
比如我要对{1,5,7,2}这四个byte类型的数字做排序,该怎么做呢?我们知道byte是占8个bit位,其实我们可以将数组中的值作为bit位的
key,value用”0,1“来标识该key是否出现过?下面看图:
View Code
在所有具有性能优化的数据结构中,我想大家使用最多的就是hash表,是的,在具有定位查找上具有O(1)的常量时间,多么的简洁优美,
但是在特定的场合下:
①:对10亿个不重复的整数进行排序。
②:找出10亿个数字中重复的数字。
当然我只有普通的服务器,就算2G的内存吧,在这种场景下,我们该如何更好的挑选数据结构和算法呢?
一:问题分析
这年头,大牛们写的排序算法也就那么几个,首先我们算下放在内存中要多少G: (10亿 * 32)/(1024*1024*1024*8)=3.6G,可怜
的2G内存直接爆掉,所以各种神马的数据结构都玩不起来了,当然使用外排序还是可以解决问题的,由于要走IO所以暂时剔除,因为我们
要玩高性能,无望后我们想想可不可以在二进制位上做些手脚?
比如我要对{1,5,7,2}这四个byte类型的数字做排序,该怎么做呢?我们知道byte是占8个bit位,其实我们可以将数组中的值作为bit位的
key,value用”0,1“来标识该key是否出现过?下面看图:
View Code
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Diagnostics; 6 using System.Threading; 7 using System.IO; 8 9 namespace ConsoleApplication2 10 { 11 public class Program 12 { 13 static byte n = 7; 14 15 static byte[] a; 16 17 public static void Main() 18 { 19 //节省空间的做法 20 a = new byte[(n >> 3) + 1]; 21 22 for (byte i = 0; i < n; i++) 23 Clear(i); 24 25 Add(4); 26 Console.WriteLine("插入4成功!"); 27 28 var s = Contain(4); 29 30 Console.WriteLine("当前是否包含4:{0}", s); 31 32 s = Contain(5); 33 34 Console.WriteLine("当前是否包含5:{0}", s); 35 36 Console.Read(); 37 } 38 39 #region 初始化所用的bit位为0 40 /// <summary> 41 /// 初始化所用的bit位为0 42 /// </summary> 43 /// <param name="i"></param> 44 static void Clear(byte i) 45 { 46 //相当于 i%8 的功能 47 var shift = i & 0x07; 48 49 //计算应该放数组的下标 50 var arrindex = i >> 3; 51 52 //则将当前byte中的指定bit位取0,&后其他对方数组bit位必然不变,这就是 1 的妙用 53 var bitPos = ~(1 << shift); 54 55 //将数组中的指定bit位置一 “& 操作” 56 a[arrindex] &= (byte)(bitPos); 57 } 58 #endregion 59 60 #region 设置相应bit位上为1 61 /// <summary> 62 /// 设置相应bit位上为1 63 /// </summary> 64 /// <param name="i"></param> 65 static void Add(byte i) 66 { 67 //相当于 i%8 的功能 68 var shift = i & 0x07; 69 70 //计算应该放数组的下标 71 var arrindex = i >> 3; 72 73 //将byte中的 1 移动到i位 74 var bitPos = 1 << shift; 75 76 //将数组中的指定bit位置一 “| 操作” 77 a[arrindex] |= (byte)bitPos; 78 } 79 #endregion 80 81 #region 判断当前的x在数组的位中是否存在 82 /// <summary> 83 ///判断当前的x在数组的位中是否存在 84 /// </summary> 85 /// <param name="i"></param> 86 /// <returns></returns> 87 static bool Contain(byte i) 88 { 89 var j = a[i >> 3] & (1 << (i & 0x07)); 90 91 if (j == 0) 92 return false; 93 return true; 94 } 95 #endregion 96 } 97 }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics; using System.Threading; using System.IO; namespace ConsoleApplication2 { public class Program { static byte n = 7; static byte[] a; public static void Main() { //节省空间的做法 a = new byte[(n >> 3) + 1]; for (byte i = 0; i < n; i++) Clear(i); Add(4); Console.WriteLine("插入4成功!"); var s = Contain(4); Console.WriteLine("当前是否包含4:{0}", s); s = Contain(5); Console.WriteLine("当前是否包含5:{0}", s); Console.Read(); } #region 初始化所用的bit位为0 /// <summary> /// 初始化所用的bit位为0 /// </summary> /// <param name="i"></param> static void Clear(byte i) { //相当于 i%8 的功能 var shift = i & 0x07; //计算应该放数组的下标 var arrindex = i >> 3; //则将当前byte中的指定bit位取0,&后其他对方数组bit位必然不变,这就是 1 的妙用 var bitPos = ~(1 << shift); //将数组中的指定bit位置一 “& 操作” a[arrindex] &= (byte)(bitPos); } #endregion #region 设置相应bit位上为1 /// <summary> /// 设置相应bit位上为1 /// </summary> /// <param name="i"></param> static void Add(byte i) { //相当于 i%8 的功能 var shift = i & 0x07; //计算应该放数组的下标 var arrindex = i >> 3; //将byte中的 1 移动到i位 var bitPos = 1 << shift; //将数组中的指定bit位置一 “| 操作” a[arrindex] |= (byte)bitPos; } #endregion #region 判断当前的x在数组的位中是否存在 /// <summary> ///判断当前的x在数组的位中是否存在 /// </summary> /// <param name="i"></param> /// <returns></returns> static bool Contain(byte i) { var j = a[i >> 3] & (1 << (i & 0x07)); if (j == 0) return false; return true; } #endregion } }
相关文章推荐
- 经典算法题每日演练——第十一题 Bitmap算法
- 经典算法题每日演练——第十一题 Bitmap算法
- 经典算法题每日演练——第十一题 Bitmap算法
- 经典算法题每日演练——第十一题 Bitmap算法
- 经典算法题每日演练——第十四题 Prim算法
- 经典算法题每日演练——第十七题 Dijkstra算法
- 经典算法题每日演练——第十二题 线段树
- 经典算法题每日演练——第六题 协同推荐SlopeOne 算法
- 经典算法题每日演练——第十九题 双端队列
- 经典算法题每日演练——第一题 百钱买百鸡
- 经典算法题每日演练——第二十二题 奇偶排序
- 经典算法题每日演练——第十八题 外排序
- 经典算法题每日演练——第十三题 赫夫曼树
- 经典算法题每日演练——第八题 AC自动机
- 经典算法题每日演练——第二十二题 奇偶排序
- 经典算法题每日演练——第二题 五家共井
- 经典算法题每日演练——第二十三题 鸡尾酒排序
- 经典算法题每日演练———25题
- 经典算法题每日演练——第二十二题 奇偶排序
- 经典算法题每日演练——第一题 百钱买百鸡