• 编程珠玑第一章的算法,Java实现,通俗易懂


    该算法也就是所谓的位图算法,用一个int表示32位,也就是实际值为1~32的数.

    按照书里说的, 该算法只适合内存有限,而磁盘和时间不限,且数字在1~MAX之间不重复的排序.

     1 package demo1;
     2 
     3 /**
     4  * Created with IntelliJ IDEA.
     5  * User: wsyang
     6  * Date: 13-11-3
     7  * Time: 8:11
     8  * To change this template use File | Settings | File Templates.
     9  */
    10 public class BitSort {
    11 
    12     public static void main(String[] args) {
    13         //每个int类型数的位数(1个int数是4个字节,1个字节等于8位,所以是32=4*8)
    14         int size = 32;
    15         //最大值
    16         int MAX= 10000000;
    17         //计算出需要多大的数组,才能按位保存MAX个数.数组中每一个元素,也就是int数,能保存32位,所以是如下算数.
    18         int arraySize = MAX/size + (MAX%size==0?0:1);
    19         System.out.println("需要"+arraySize+"个数组元素");
    20         int[] datas = new int[arraySize];
    21 
    22         //测试数据
    23         int[] orginal = new int[]{5,888,4,2,6,7,3,10,567,456,234,123,66666,55555,3333333,8908764};
    24 
    25         //完成位图的填充
    26         for(int i=0;i<orginal.length;i++){
    27             int v = orginal[i];//原始值
    28             //假设数值是33,因为1个int也就是32位只能表示1~32,因此,需要算出:
    29             int index = v/size + (v%size==0?0:1)-1;//数组第几项才能表示目标数v
    30             int pos = v % size - 1;//偏移量,也就是数组的index位置的int数的第几位才是这个数
    31             //这里用了按位与运算,因为假设原值是000100,计算出偏移量是30,也就是说,倒数第二位是1,合并进去就是001 10.
    32             //因此这里按位与运算最合适
    33             int newResult = datas[index]  | 1<< 31-pos;//新结果
    34             //更新值
    35             datas[index]=newResult;
    36             System.out.print("原始值" + v);
    37             System.out.print("下标" + index);
    38             System.out.print("偏移" + pos);
    39             System.out.print("新结果" + newResult);
    40             System.out.println();
    41         }
    42         //遍历位图,输出结果
    43         for(int i=0;i<datas.length;i++){
    44             int data = datas[i];
    45 
    46             //有了data这个十进制数,如何得到她的二进制的每位值呢?
    47             //很简单,需要得到某位的值,就将该数右移31-第几位,并将除末位外的所有位置为0,就能知道该位实际值.
    48             for(int index=0;index<31;index++){
    49                 //上条注释所言的计算方法
    50                 int posVal = (data >> (31-index)) & 1;
    51 
    52                 if(posVal==1){
    53                     //如果该位是1,那么说明该位是有值的,输出她
    54                     //由于我们进行了拆分,也就是说当i=1时,基数是32开始,偏移量为1,就是33
    55                     int result = size*i + index+1;
    56                     System.out.print(result + ",");
    57                 }
    58             }
    59 
    60         }
    61     }
    62 }

     这个程序的输出是:

    需要312500个数组元素
    原始值5下标0偏移4新结果134217728
    原始值888下标27偏移23新结果256
    原始值4下标0偏移3新结果402653184
    原始值2下标0偏移1新结果1476395008
    原始值6下标0偏移5新结果1543503872
    原始值7下标0偏移6新结果1577058304
    原始值3下标0偏移2新结果2113929216
    原始值10下标0偏移9新结果2118123520
    原始值567下标17偏移22新结果512
    原始值456下标14偏移7新结果16777216
    原始值234下标7偏移9新结果4194304
    原始值123下标3偏移26新结果32
    原始值66666下标2083偏移9新结果4194304
    原始值55555下标1736偏移2新结果536870912
    原始值3333333下标104166偏移20新结果2048
    原始值8908764下标278398偏移27新结果16
    2,3,4,5,6,7,10,123,234,456,567,888,55555,66666,3333333,8908764,
    Process finished with exit code 0

  • 相关阅读:
    理财课堂笔记第9天
    李筱懿的《先谋生,再谋爱》读后感
    bat想要写一个卸载软件的脚本,最后宣布失败[未完待续...]
    理财课堂日记第7天
    理财课堂日记第6天
    理财课堂日记第5天
    bat脚本登陆ftp服务器
    理财课堂笔记第4天
    理财课堂日记第3天
    理财课堂日记第2天
  • 原文地址:https://www.cnblogs.com/dycg/p/3404593.html
Copyright © 2020-2023  润新知