【编程珠玑】【第一章】位向量的实现

问题:给定输入文件,文件中每条记录是一个整型数(不重复),每条记录最大为nn<=10000000,要求对文件中所有记录排序(从小到大),然后输入到给定文件。

限制:主存不超过1MB

位图排序就是使用一张表来记录关键字的存在状态(存在或不存在),然后通过采集到的状态(/不在)通过一次遍历来确定序列顺序。

1)首先找到该整数对应的数组的下标(i/32)。由于数组中的每一个整数有32位(假设int型为32位),这32位可以表示32个整数。

2)找到该整数在对应整数的位坐标pos

3)设置或清除该整数的位。

1.位向量的实现

#include <stdio.h>  
#include <stdlib.h>  
#define SHIFT 5  
#define MASK 0x1F  
#define N 10000000  
int a[1 + N/32];  
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 = 0;  
    //int  top = 1 + N/BITSPERWORD;  
    //memset(a, 0, sizeof(a)*sizeof(int));  
    for( i = 0; i < 100; i++ )
        set( i*2 );
    for( i = 0; i < 200; i++ )
        printf("%d",test(i) ? 1:0 );
    puts("/n");
    return 0;  
}        

实现说明:
    i >> SHIFT:将i向右移动5位,相当于将i除以32位。因为一个int是32位,所以结果表示i在第几个int数组成员中;1 << (i & MASK):使用掩码留下i的低5位相当于获得了余数,标识着在当前int中的第几位,所以相应的把0001中的1移动这么多位到相应的位上,完成置位操作。

2.位排序算法的实现

因为需要对1000000个乱序数据进行位图排序,所以首先要得到0~10000000区间的乱序输入数字序列(没有重复),所以这里首先根据“rand函数”笔记中的方法从0~N中选择m个互异的数字并进行随机交换打乱顺序的方法,获得这个输入序列,其中N和M均为10000000。

#include <stdio.h>  
#include <stdlib.h>  
#include <time.h>
//#define CLOCKS_PER_SEC 1000
#define BITSPERWORD 32     //int的位数
#define SHIFT 5  
#define MASK 0x1F  
#define N 100  
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 randint( int a, int b ){
    return a + (RAND_MAX * rand() +2* rand()) % (b + 1 - a);
}
int main(void){
    int * arr = (int*)malloc(sizeof(int)*N);
    int i,j;
    for(i = 0;i<N;i++){
        arr[i] = i ;
        clr(i);
    }
    for(i =0;i<N;i++){
        j = randint(i,N-1);    // randint(int i,int j) 产生i与j 之间的随机数
        int t = arr[i];        //swap(x[i],x[j]):交换x[i],x[j]
        arr[i] = arr[j];
        arr[j] = t;
    }
    for(i = 0; i < N; i++){
        printf("%d\n",arr[i]);
    }
    
    clock_t start,end;
    start=clock();
    for(i = 0; i < N;i++)
        set(arr[i]);
    for(i = 0; i < N; i++){
        if(test(i)){
            printf("%d\n",i);
        }
    }
    end=clock();
    printf("time=%f ms \n",(double)(end-start)/CLOCKS_PER_SEC);
    return 0;
}
原文地址:https://www.cnblogs.com/blastbao/p/8290482.html