zoukankan      html  css  js  c++  java
  • 如何在很大数量级的数据中(比如1个亿)筛选出前10万个最小值?之七

    数据继续增加,麻烦很多。下面给出一个方案:

    void shift(int data[], int i, int length)                       //筛选算法
    {
      for(int c; c= i* 2+ 1, c< length; )
        if(c+= c+ 1< length && data[c]< data[c + 1], data[i]<= data[c])
          swap(data[c], data[i]),     i= c;
        else
          break;
    }
    //----------------------
    #define   i1K                 1024
    #define   i1M                 i1K* i1K
    #define   BlockSize           (100*i1M)
    void GetTopK(int sele, int All)
    {
      double times[3]= { GetTickCount() };
    
      int *Data0= new int[sele], *Data1= new int[BlockSize], File0Number;
      String path= "D:\", name= "inFile.dat";
      //第一步,打开或文件不存在时,做出随机数据文件。
      if(File0Number= open(String(path+ name).c_str(), 0), File0Number== -1)
      {
        File0Number= creat(String(path+ name).c_str(), 2);
        for(int all= All, size= BlockSize; all> 0; all-= size)      //减去做好的
          for(int i= 0; i<= size; i++)
            if(i== size)
              _rtl_write(File0Number, Data1, min(size, all));       //写出一块数据
            else
              Data1[i]= random(BlockSize);                          //得随机数
        lseek(File0Number, 0, SEEK_SET);                            //回文件首
      }
      times[0]= GetTickCount()- times[0];
      times[1]= GetTickCount();
      //第二步,取出数据。
      _rtl_read(File0Number, Data0, sele);
      for(int i= (sele- 2)/ 2; i>= 0; i--)
        shift(Data0, i, sele);                                      //建堆
      for(int i, size= 1; size> 0; )
        for(size= _rtl_read(File0Number, Data1, BlockSize), i= 0; i< size; i++)
          if(Data0[0]> Data1[i])                                    //小值
            Data0[0]= Data1[i],   shift(Data0, 0, sele);            //加小值,再成堆
      times[1]= GetTickCount()- times[1];
      times[2]= GetTickCount();
      //第三步,验证()
      //略
      times[2]= GetTickCount()- times[2];
    delete []Data0; delete []Data1; }

      它先判断是否有原始数据文件。无则创建并写入随机数据。

    再取出sele个数据。建最大堆。继续读出数据块。并逐步挑出最小数。

    程序看起来,还是很简单的。但,有两个问题:

    1、int 数的表达范围,只有二十亿。程序应该考虑数的表达范围问题了。

    2、验证有麻烦:之前,我们①用标准排序与结果比较。②还可用结果中的最大数,与取值后余下的数做比较,要是得到这个最大数都小于或等余下的数,就证明结果是正确的。现在,数太多,没法用标准排序。而取数后的数,还是保留在原始数据中。也就不能用法②。

    暂时就这样了。待想出验证办法再说。

  • 相关阅读:
    Big-data:Linux基础(04)--快捷键
    Big-data:Linux基础(03)
    Big-data:Linux基础(02)
    [mysql]删除和修改
    git使用两个异常处理
    jmeter函数使用以及json格式的后置处理器
    jmeter遇到中文不可见
    jmeter参数化
    GIT简易使用
    mysql基本语句(更新中)
  • 原文地址:https://www.cnblogs.com/oldtab/p/4465890.html
Copyright © 2011-2022 走看看