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

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

 

posted @ 2015-04-29 14:23  汇铁  阅读(666)  评论(0编辑  收藏  举报