编程珠玑 -- 利用位图排序
2014-04-28 22:42
232 查看
1. 如何利用位图或位向量表示集合
书中描述的是可以用20位长的字符串来表示一个所有元素都小于20并不重复 的简单的非负数集合。
即 20位的字节数组array[ ], 如果集合中的有数字 2 则 array[ 2 ] = 1, 如果集合中有数字3 则array[ 3 ] = 1.
例如{1,2,3,5,8,13} --> 0111 0100 1000 0100 0000
注意: 本例中是小于20, 0~19, 所以数组角标是0开始 0~19,之前网上有些例子角标是 1~20 , 所以数组会有偏移。
2. 利用位图排序对数字有一定的要求:
(1).输入数据限制在相对较小的范围内,或者说必须知道集合中数值的范围,必须知道最大值。
(2).数据没有重复,如果有重复的数,单纯排序没问题,但是不能记录重复的数有多少个;
(3).除了单一整数外,没有任何其他关联数据.
3. 示例代码
java
C/C++语言实现程序: 转子 http://www.cnblogs.com/dolphin0520/
C实现
书中描述的是可以用20位长的字符串来表示一个所有元素都小于20并不重复 的简单的非负数集合。
即 20位的字节数组array[ ], 如果集合中的有数字 2 则 array[ 2 ] = 1, 如果集合中有数字3 则array[ 3 ] = 1.
例如{1,2,3,5,8,13} --> 0111 0100 1000 0100 0000
注意: 本例中是小于20, 0~19, 所以数组角标是0开始 0~19,之前网上有些例子角标是 1~20 , 所以数组会有偏移。
2. 利用位图排序对数字有一定的要求:
(1).输入数据限制在相对较小的范围内,或者说必须知道集合中数值的范围,必须知道最大值。
(2).数据没有重复,如果有重复的数,单纯排序没问题,但是不能记录重复的数有多少个;
(3).除了单一整数外,没有任何其他关联数据.
3. 示例代码
java
public class _1位图算法排序 { @Test public void test1(){ Date date = new Date(); Random random = new Random(); // 排序的数都小于n 并且不重复 int n = 1000000; byte[] array = new byte ; // n个随机数(0-n)位图,对应数组位置致1 for(int i=0; i<n; i++){ int num = random.nextInt(n); System.out.println("num: " + num); array[num] = 1; } for(int j=0; j<n; j++){ if(array[j]==1){ System.out.println(j); } } System.out.println(date); System.out.println(new Date()); } }
C/C++语言实现程序: 转子 http://www.cnblogs.com/dolphin0520/
C实现
/*位图 2011.10.18*/ #include <stdio.h> #define MAX 1000000 #define SHIFT 5 #define MASK 0x1F #define DIGITS 32 int a[1+MAX/DIGITS]; void set(int n) //将逻辑位置为n的二进制位置为1 { a[n>>SHIFT]=a[n>>SHIFT]|(1<<(n&MASK)); //n>>SHIFT右移5位相当于除以32求算字节位置,n&MASK相当于对32取余即求位位置, } //然后将1左移的结果与当前数组元素进行或操作,相当于将逻辑位置为n的二进制位置1. void clear(int n) { a[n>>SHIFT]=a[n>>SHIFT]&(~(1<<(n&MASK))); //将逻辑位置为n的二进制位置0,原理同set操作 } int test(int n) { return a[n>>SHIFT] & (1<<(n&MASK)); //测试逻辑位置为n的二进制位是否为1 } int main(int argc, char *argv[]) { int i,n; for(i=1;i<=MAX;i++) { clear(i); } while(scanf("%d",&n)!=EOF) { set(n); } for(i=1;i<=MAX;i++) { if(test(i)) printf("%d ",i); } return 0; }C++实现
/*位图C++STL实现 2011.10.19*/ #include <iostream> #include<bitset> #define MAX 1000000 using namespace std; bitset<MAX+1> bit; //声明一个有(MAX+1)个二进制位的bitset集合,初始默认所有二进制位为0 int main(int argc, char *argv[]) { int n,i; while(scanf("%d",&n)!=EOF) { bit.set(n,1); //将第n位置1 } for(i=0;i<=MAX+1;i++) { if(bit[i]==1) printf("%d ",i); } return 0; }
相关文章推荐
- 【编程珠玑】第一章位图排序
- 编程珠玑习题:多趟位图排序,数字不重复出现
- 编程珠玑--位图在排序中的使用
- 编程珠玑--位图在排序中的使用
- 编程珠玑:位图排序海量整数
- 编程珠玑习题:数字重复出现位图排序
- 【编程珠玑-读书笔记】用位图解决排序问题--仔细分析问题的重要性
- 编程珠玑之第一章习题6给每个整数不超过10次的100w数据排序的测试用例
- 对一千万条数据进行排序---编程珠玑第二版 第一章
- 对一千万条数据进行排序---编程珠玑第二版 第一章
- JAVA版位图排序(算法珠玑开篇的例子)
- 【编程珠玑】读书笔记 第十一章 排序
- 编程珠玑--第一章使用位图
- 编程珠玑开篇--磁盘文件排序问题
- 编程珠玑之第一章习题3:度量100w整数排序的运行时间
- Hardwood Species(利用STL中自带的排序功能编程的实验范例)
- A - Hardwood Species(7.1.1)(利用STL中自带的排序功能编程的实验范例)
- 【编程珠玑】排序与位向量
- [数据结构]利用位图排序
- 编程珠玑: 14章 堆 14.1实现一个堆,对数组排序 -------解题总结