zoukankan      html  css  js  c++  java
  • 编程珠玑位排序(bitsort)

    在《编程珠玑》一书上,有一题是将一堆不重复的数进行排序,这些数的值大小位于[0, 10000000).
    然后作者在书后给出的答案确实很精辟,利用位排序将这个问题轻而易举的解决了。
    首先弄懂i>>SHIFT相当于i/32,i&MASK相当于i%32.
    题目中说了
     
    Replace above 2 lines with below 3for word-parallel init
    int top =1+ N/BITSPERWORD;
    for (i =0; i < top; i++)
    a[i]
    =0;


    那么就采用这个,把a数组中的元素都设置为0.
    整个程序的思想就是:
                1.每个整数有32位,那么它就可以表示32个数,分别对应每bit位为1.
                2.然后把10000000个数分为1+N/BITSPERWORD组(相当于有这么多个桶),每组包含接近32个数。
    上面的解释可能仍不到位,那我们来看具体的函数:
     
    对于set函数,我们可以这样理解,
                 arr[i>>SHIFT] |= (1<<(i&MASK))可以转化为
                 arr[i/32] = arr[i/32] | (1<<(i%32))
    i%32必然处于区间[0, 31],那么1<<(i%32)就是将bit位1向前移动(i%32)位,然后和arr[i/32]相或,因而arr[i/32]的第(i%32)位就为1.
     
    对于test函数,就是上面过程的反过程了。它是用来判断i个这个数是否存在,即arr[i/32]的相应bit位是否为1.
     
    最后,就做排序了,
          for (int i = 0; i < N; i++)
    由于[0, N)已经是从小到大排序好的,那么我们只需判断每个数是否存在,若存在,就输出,所以输出结果也就是排序的了。
    复制代码
    #include <stdio.h>

    #define N 10000000
    #define BITSPERWORD 32
    #define SHIFT 5
    #define MASK 0x1F

    int arr[1+ N/BITSPERWORD];

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

    int test(int i)
    {
      
    return arr[i>>SHIFT] & (1<<(i&MASK));
    }

    int main()
    {
      
    ////先在文本文件中生成N个数
      //FILE* file = freopen("in", "w", stdout);
      
    //if (file != NULL)
      
    //{
        
    // for (int i = 0; i < N; i++)
        
    // {
            
    // printf("%d\n", N - 1 -i);
        
    // }
        
    // fclose(file);
      
    //}

      FILE
    * in_file = freopen("in", "r", stdin);
      FILE
    * out_file = freopen("out", "w", stdout);

      
    if (in_file != NULL)
      {
        
    int d;
        
    while(scanf("%d", &d) != EOF)
          
    set(d);
        fclose(in_file);
      }

      
    if (out_file != NULL)
      {
        
    for (int i =0; i < N; i++)
          
    if (test(i))
            printf(
    "%d\n", i);
      }
      fclose(out_file);
      
    return0;
    }
    复制代码
     
    ---
    可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明
     
  • 相关阅读:
    WPF项目学习.一
    AtCoder Beginner Contest 210 A~D 题解
    P7715 「EZEC-10」Shape 题解
    P6216 回文匹配 题解
    字符串学习笔记
    #2742. 「JOI Open 2016」销售基因链
    树状数组学习笔记
    2021 省选游记
    AtCoder Beginner Contest 196 E
    AtCoder Regular Contest 113 A~D题解
  • 原文地址:https://www.cnblogs.com/10jschen/p/2665910.html
Copyright © 2011-2022 走看看