• 第 1 章 第 3 题 空间敏感排序问题 位向量实现( 数组位向量 )


    问题分析

      本题解答分成以下几个步骤:

      1. 创建一个用来测试的数据文件( 内含10000000个整数 )

      2. 编写位向量版的排序程序

      3. 测试2中排序程序所用时间和本章第 1 题排序所用时间

    第一步:创建一个用来测试的数据文件( 内含10000000个整数 )

      这里我编写了一个小程序来创建这个数据文件,代码如下:

     1 #include <iostream>
     2 #include <fstream>
     3 #include <string>
     4 #include <cstdlib>
     5 
     6 using namespace std;
     7 
     8 #define N 10000000
     9 
    10 int main()
    11 {
    12     string filename;
    13     cout << "输入要创建的数据文件名: " << endl;
    14     cin >> filename;
    15 
    16     fstream io;
    17     io.open(filename.c_str(), fstream::out);
    18     if (!io) {
    19         cout << "打开文件失败!" << endl;
    20         return 1;
    21     }
    22 
    23     /*
    24      * 使用随机数函数产生随机数并存进文件
    25     */
    26     for (int i=0; i<N; i++) {
    27         io << rand()%10000000 << " ";
    28     }
    29     io.close();
    30 
    31     cout << "成功创建数据文件(记录类型:整型 记录个数:10000000)" << endl;
    32     
    33     return 0;
    34 }

    编译运行后即可获得一个新的目标数据文件( 数据文件文件名由用户指定 )。

    第二步:编写位向量版的排序

     1 #include <iostream>
     2 #include <fstream>
     3 #include <string>
     4 
     5 using namespace std;
     6 
     7 // 每个整数的位数
     8 #define BITSPERWORD 32
     9 // 每次位移量
    10 #define SHIFT 5
    11 // 取模掩码
    12 #define MASK 0x1F
    13 // 位向量的元素个数
    14 #define N 10000000
    15 
    16 // 模拟数组
    17 int a[1 + N/BITSPERWORD];
    18 
    19 /*
    20  * 函数功能:置位向量第i位为1
    21  * 函数说明:" i>>SHIFT "等于" i/32 " 获取到位向量目标位对应的模拟数组元素的位置
    22             " i & MASK "等于" i%32 " 获取到位向量目标位在对应的模拟数组元素中的位置
    23             " 1<<(i & MASK) " 表示一个除了要设置的那位其他位都是0的整数
    24 */
    25 void set (int i) {
    26     a[i>>SHIFT] |= (1<<(i & MASK));
    27 }
    28 
    29 /*
    30  * 函数功能:置位向量第i位为0
    31  * 函数说明:" i>>SHIFT "等于" i/32 " 获取到位向量目标位对应的模拟数组元素的位置
    32             " i & MASK "等于" i%32 " 获取到位向量目标位在对应的模拟数组元素中的位置
    33             " 1<<(i & MASK) " 表示一个除了要清空的那位其他位都是0的整数
    34 */
    35 void clr (int i) {
    36     a[i>>SHIFT] &= ~(1<<(i & MASK));
    37 }
    38 
    39 /*
    40  * 函数功能:获取位向量的第i位
    41  * 函数说明:" i>>SHIFT "等于" i/32 " 获取到位向量目标位对应的模拟数组元素的位置
    42             " i & MASK "等于" i%32 " 获取到位向量目标位在对应的模拟数组元素中的位置
    43             " 1<<(i & MASK) " 表示一个除了要获取的那位其他位都是0的整数
    44 */
    45 int tst (int i) {
    46     return a[i>>SHIFT] & (1<<(i & MASK));
    47 }
    48 
    49 
    50 int main()
    51 {
    52     /*
    53      * 清空位向量
    54     */
    55     for (int i=0; i < N; i++) {
    56         clr(i);
    57     }
    58 
    59     string filename;
    60     cout << "输入数据文件名( 当前目录下 ):";
    61     cin >> filename;
    62     
    63     fstream io;
    64     io.open(filename.c_str());
    65     if (!io) {
    66         cout << "打开文件失败" << endl;
    67     return 1;
    68     }
    69 
    70     /*
    71      * 根据数据文件记录给位向量赋值
    72      * 赋值完了以后其实已经" 完成排序了 "
    73     */
    74     int data;
    75     while (io >> data) {
    76         set(data);
    77     }
    78 
    79     io.close();
    80     io.clear();
    81     io.open(filename.c_str(), fstream::out | fstream::trunc);
    82 
    83     /*
    84      * 从位向量获取数据并写回数据文件
    85     */
    86     for (int i=0; i <N; i++) {
    87         if ( tst(i) ) {
    88             io << i << " ";
    89         }
    90     }
    91 
    92     io.close();
    93 
    94     return 0;
    95 }

    运行测试参见下一步

    第三步:测试2中排序所用时间和本章第 1 题排序所用时间

      用第一步中的程序创建一个数据文件并拷贝一份,然后用上面的排序程序处理数据文件并获取运行时间,再用本章第一题的排序程序处理数据文件的拷贝并获取运行时间,比较之:

     很显然,本书作者给出的排序效率很高,接近第一题中排序程序的两倍。

     说明

      不知道怎么测试程序运行时间的话点这里

  • 相关阅读:
    大数乘法
    大数阶乘
    存js导入excel文件
    设计模式详解
    javascript的api设计原则
    从零开始nodejs系列文章
    git的学习
    如何暴力学英语
    Vsftpd
    shell命令学习
  • 原文地址:https://www.cnblogs.com/scut-fm/p/3238591.html
Copyright © 2020-2023  润新知