如何在Java中编写位排序程序?

时间:2012-01-28 06:31:13

标签: java algorithm sorting

大家好我理解Bentley经典编程珍珠中的bitsort程序有问题。我是Bitmask和Bitset的新手,所以我无法理解这些概念。 实际上该程序是针对“如何对磁盘文件进行排序?”。以下是代码

#include <stdio.h>
#define BITSPERWORD 32
#define SHIFT 5
#define MASK 0x1F
#define N 10000000
int a[1 + N/BITSPERWORD];

void set(int i) {
    a[i>>SHIFT] |=  (1<<(i & MASK));
}

void clr(int i) {
    a[i>>SHIFT] &= ~(1<<(i & MASK)); 
}
int  test(int i){ 
    return a[i>>SHIFT] &   (1<<(i & MASK)); 
}

int main()
{   int i;
    for (i = 0; i < N; i++)
        clr(i);
/*  Replace above 2 lines with below 3 for word-parallel init
    int top = 1 + N/BITSPERWORD;
    for (i = 0; i < top; i++)
        a[i] = 0;
 */
    while (scanf("%d", &i) != EOF)
        set(i);
    for (i = 0; i < N; i++)
        if (test(i))
            printf("%d\n", i);
    return 0;
}

有人可以向我解释一下这段代码吗?如果可能,请提供Java版本。实际上,我只对Java感到满意,这就是我要问的原因。这不是作业。

可能重复:link1 link2

2 个答案:

答案 0 :(得分:3)

我们得到的数字将介于0到N之间,

所以我们创建一个大的BitSet,这是一个很大的布尔数组(最后解释工作),但占用的内存较少(每个位在技术上都是一个布尔值)

所以Jon做了什么,他将整个位设置为false,然后对于遇到的每个数字,他将该Bit设置为true ....最后,他遍历bitset并为每个{{1他打印索引的条目。这将对一个数组进行排序,我们知道元素总是位于true之间。

注意:上述算法会因重复而失败。

现在是Bit Mask的东西......

假设我有一个整数数组(sizeof(int)= 32)但我想将它用作N大小的布尔数组。那么我真的需要多少元素?这是0 to N

N/32

现在,如果我想访问BitSet的int a[1 + N/BITSPERWORD]; // allocates BitSet of N size 元素,那么索引的工作原理。

例如,ith

所以i = 49包含0-31位,a [1]包含32-63。

a[0](给你哪个 int array 元素包含该位) 和a[i/32]该元素中的位位置。

因此对于i % 32i= 49会告诉您第49位是否已设置。

如果您熟悉按位优化,您知道除以因子2,实际上是将数字右移多少因素。

32 = 2 ^ 5 ...因此a[49/32] & ( 1 << (i % 32) )X/32

相同

X >> 5也与X % 32

相同 如果设置位置的位集,

X & 0x1f函数给出1,

test将该位置的bitset清零(

clr将位置的位集设置为1。

唷!希望有所帮助。

答案 1 :(得分:2)

如果我没记错的话,在这种情况下使用一个位集就可以有效地跟踪磁盘文件中出现的整数。当传递文件时,通过将数组的第i位设置为1来指示整数i的存在。

例如,如果[0] = 5,则[0]处的32位二进制值(记住BITSPERWORD常量假定代码在32位机器上运行)为0 ... 01010。这表示文件中存在整数1和3,但在文件中找不到整数2和4 - 31。

主要方法的步骤是:

  1. 将数组中的所有位a设置为0.
  2. 扫描文件,如果遇到整数i,则将数组的第i位设置为1。
  3. 测试是否在文件中找到了整数i,以及是否打印了整数 到了屏幕。