《编程珠玑》第一章第一题就相当的精彩,做个笔记。题目如下:
输入: 一个包含n个正整数的文件,每个正整数小于n,n等于10的7次方(一千万)。并且文件内的正整数没有重复和关联数据。
输出: 输入整数的升序排列
约束: 限制在1M内存,充足的磁盘空间
假设整数占32位,1M内存可以存储大概250000个整数,第一个方法就是采用基于磁盘的合并排序算法,第二个办法就是将0-9999999切割成40个区间,分40次扫描(10000000/250000),每次读入250000个在一个区间的整数,并在内存中使用快速排序。书中提出的第三个解决办法是采用bitmap(或者称为bit vector)来表示所有数据集合(注意到条件,数据没有重复),这样就可以一次性将数据读入内存,减少了扫描次数。算法的伪代码如下:
阶段1:初始化一个空集合
for i=[0,n)
bit[i]=0;
阶段2:读入数据i,并设置bit[i]=1
for each i in the input file
bit[i]=1;
阶段3:输出排序的结果
for i=[0,n)
if bit[i]==1
write i on the output file
这个算法的时间复杂度在O(n),用c语言写的版本可以在10秒内完成任务!c语言的源码在该书主页上有,这里给一个java的测试版,加上我的理解注释:
/**
* Created by IntelliJ IDEA.
* User: zhuangxd
* Date: 2008-1-7
* Time: 14:30:44
*/
public class BitSortTest {
private static final int BITSPERWORD = 32; //整数位数
private static final int SHIFT = 5;
private static final int MASK = 0x1F; //5位遮蔽 0B11111
private static final int N = 10000000;
//用int数组来模拟位数组,总计(1 + N / BITSPERWORD)*BITSPERWORD位,足以容纳N
private static int[] a = new int[(1 + N / BITSPERWORD)];
public static void main(String[] args) {
bitsort(new int[]{1, 100, 2, 10000, 9999, 4567, 78902});
}
public static void bitsort(int[] array) {
for (int i = 0; i < N; i++)
clr(i); //位数组所有位清0
for (int i = 0; i < array.length; i++)
set(array[i]); //阶段2
for (int i = 0; i < N; i++)
if (test(i))
System.out.println(i);
}
//置a[i>>SHIFT]的第(i & MASK)位为1,也就是位数组的第i位为1
public static void set(int i) {
a[i >> SHIFT] |= (1 << (i & MASK));
}
//置a[i>>SHIFT]的第(i & MASK)位为0,也就是位数组的第i位为0
public static void clr(int i) {
a[i >> SHIFT] &= ~(1 << (i & MASK));
}
//测试位数组的第i位是否为1
public static boolean test(int i) {
return (a[i >> SHIFT] & (1 << (i & MASK))) == (1 << (i & MASK));
}
}
分享到:
相关推荐
实现位图排序,其中假设n为10 000 000,且输入文件包含1 000 000个正数;具体细节详见《编程珠玑》第一章问题; 由于数据的大小问题,在这#define N 1000,即数据在1000以内的100个数据,进行排序(当然由于随机数...
本文实例讲述了PHP实现bitmap位图排序求交集的方法。分享给大家供大家参考,具体如下: 初始化一串全为0的二进制; 现有一串无序的整数数组; 如果整数x在这个整数数组当中,就将二进制串的第x位置为1; 然后顺序读取这...
输入:一个最多包含n个正整数的文件,每个数都小于n,其中n=10^7,。如果在输入文件中有任何整数重复出现就是致命错误。没有其他数据与该整数关联。 输出:按升序排列的输入整数列表。 约束:最多有(大约)1MB的...
在《编程珠玑》一书里提到了一种算法导论里没有提到过的位图排序方法,这种排序方法是通过牺牲空间效率来追求时间效率(线性时间)以达到时间-空间折中与双赢的目的。本文以实例形式简单讲一下位图排序思想。 一、...
位图排序算法的优势在于其时间复杂度为O(n),在内存开销方面,位图排序只需要足够的位数来表示数据集合中所有可能的值。不过,这种方法在某些情况下仍然存在限制,例如当输入文件中的整数范围非常大时,可能需要超过...
位图排序是一种特殊的排序算法,尤其适用于处理包含无重复元素的整数集合。该方法利用了计算机内存中的一位可以代表一个状态的事实,通常用于表示一个整数是否存在。位图排序的基本思想是创建一个与待排序数据最大值...
位图排序是一种使用位运算的高效排序方法,特别适合于排序那些可以表示为固定范围的整数数组。它通过建立一个位图,每一位对应一个数据值,然后依次检查每个数据值,并在位图上相应位置置为1,最终通过位图直接生成...
【部分内容】:介绍了使用位图排序解决十亿个QQ号判断问题的思路与方法。 在Java面试中,位图排序是一种有效的数据处理策略,特别是在处理大量数据且内存有限的情况下。本例中,问题是如何在一个十亿个QQ号的列表中...
位图法排序是一种在特定情况下效率较高的排序技术,尤其适用于数据范围相对较小的整数排序。这种方法基于位操作,利用数组来表示一个位图,其中每一位对应一个可能的数值。在Java中,虽然标准库中的排序算法如`...
位图必须是黑白单色并旋转270度,然后通过添加到下载位图排序中。连接模块和电脑后,选择正确的串口,使用“状态测试”检查连接,然后下载位图到模块的FLASH中。下载完成后,断电并切换模块至正常模式,再次上电,就...
根据给定的文件信息,我们可以总结出以下关于“二分法排序算法C语言实现”的相关知识点: ### 1. 二分法搜索算法原理 二分法搜索算法,也称为折半查找算法,是一种在有序数组中查找特定元素的搜索算法。其基本思想...
2. 不可对重复的数据进行排序和查找。 C# 中的 BitMap 实现 在 .NET 中已经实现了 BitMap 的数据结构——BitArray,我们可以直接使用官方的 BitArray 来解决问题。但是,我们也可以参照 .NET 源码实现一个简化版的...
然后,这些帧按照特定的帧率进行排序和组合,形成连续的动态画面。 4. **编程实现**:通常,这个过程可以通过编程语言如C++、Python或Java来实现,利用图像处理库如OpenCV、FFmpeg等。例如,在OpenCV中,可以使用...
`res`文件夹通常包含应用程序所需的资源,如位图、图标等,而`sortTest.dsw`是Visual Studio的工作空间文件,用于管理项目。 在MFC环境中,动态演示排序算法可能涉及到使用C++的绘图函数,如GDI(Graphics Device ...
1. ORDERUP.BMP和ORDERDW.BMP:这可能是两个位图文件,分别表示升序和降序的图标。在PowerBuilder中,可以将这些图标设置到DataWindow的列标题上,以视觉上指示当前的排序状态。 2. DWSORT.PBL:这是一个Power...
- .BMP 文件是位图图像文件,通常用于存储项目中的图标或图片资源。 - .CFG 文件是配置文件,可能包含了项目的设置和编译选项。 - .DCU 文件是编译后的单元文件,包含了编译过的Pascal源代码,是DELPHI编译后生成的...
在图像处理领域,有时我们需要分析位图(Bitmap)中的颜色分布,找出最常出现的颜色,这一过程称为“颜色直方图”分析。本主题将深入探讨如何使用不同的算法和技术来解决这个问题,包括位图的基本概念、颜色表示法、...