我遇到一个棘手的问题,本来很容易解决,但由于数据量太大,总是执行时间太长,无法达到要求,问题描述如下:
有n个文本格式的数据文件(大约10-30个),每个文件大小都在10M左右,约50-60万行数据,其中数据为双色球的彩票号码,一注号码写一行。现在要求这n个文件的号码的交集,更重要的一点是,要求可以设置容错条件,如容错条件为8-10,表示要取出符合这样条件的号码:这号码在8个到10个文件中有(意思与在所有文件中共出现8-10次相同)超过或少于的不要。
我用delphi做了一个,少数据量的可以,但一用上面这么大的文件求,一执行就没有反映了,也占内存很大。请问高手有没有好方法解决,delphi中的集合运算,最多只能255个元素,不能用,多线程可以解决类似问题吗,我业余编程,水平很差急盼请指教!
我不知我有多少分,解决了所有分奉送!

解决方案 »

  1.   

    我用过pb的数据库试过,你想想,如果要在数据库中统计,这么大的数据量,要保存进数据库,要多久啊导入数据就要好久。更主要是保存的时候太长了,不保存进数据库,又没法统计。
    保存了后,可以用sql语句完成的,但,保存太慢了。没有成功过。
    用pb的数据窗口做,使用Filter实现,可以不保存,但也是量太大。导入时间太长以至死机
    请求帮助!!!!!!!
      

  2.   

    用oracle,分区,建索引,
    你的数据量的确较大(30*60=1800万),但对于oracle来说,完全可以完成你统计
    (我们作过的最大数据量是100万/天,每月3000万)
    不过,你的硬件也要跟上
    自已用算法作.不一定有专用数据库速度快
      

  3.   

    内存有512M以上的话,全部弄内存里处理。
    将每个串分成两段,做成二维数组,用TStringList, 并利用它的Objects存放第二维.
      

  4.   

    谢谢 ahjoe(强哥) ,能不能给段示例代码?
    我做的速度很慢,可能是处理的不好,我也用了TStringList, 但没用它的Objects,因为不知道这个。我后来建立了个1M多了都很慢。希望你把你的代码贴上来
    “用oracle,分区,建索引,”是个办法,但不方便个人用。
      

  5.   

    对“将每个串分成两段,做成二维数组,用TStringList, 并利用它的Objects存放第二维.”不是很清楚,希望详细说明
      

  6.   

    这里下载源码及测试程序, WindowsXP 512M内存下运行正常
    http://www.ahjoe.net/z/BigSORT.zipGent.exe  生成数据文件;
    BSort.exe 排序并处理数据, 最后输出到文件.600万行数据(处理1800万行512M内存不够),统计完也就几分钟时间.如果内存不够处理你的所有数据,算法要改一下,将所有数据排序分解到多个文件。每个文件再使用上面的算法单独处理, 最后再将结果合到一起。
      

  7.   

    非常感谢ahjoe(强哥),我研究一下!!!
      

  8.   

    (意思与在所有文件中共出现8-10次相同)  ??没理解,写错字了吧
    ---------------------------------------
    你的意思是不是这样,如果给定条件为8-10,则在所有文件中的查找号码,将出现次数为>=8,<=10的号码找出来??我是这样做的。
    1:将所有文件加载到一个StringList中。
    2:对StringList进行排序,就是调用它的Sort ;
    从第1 位开始向下检索一遍,因为所有相同的数字都以排到了一起,所以只要检查连续相同的数个数是否符全条件就可以了程序很简单。
      

  9.   

    FStringList 以加载了全部的数据,Memo1中输入符合条件的记录
    var
      i,L:Integer;
      m:Integer;
    begin
      Memo1 .Lines .Clear;
      FStringList.Sort;
    {检查相同}
      L:=FStringList .Count -1;
      m:=1;
      for i:=1 to L do
      begin
        if FStringList .Strings [i]=FStringList .Strings [i-1] then
          inc(m)
        else
        begin
          if (m>=8)and(m<=10) then //是否否合条件
            Memo1 .Lines .Add(FStringList.Strings [i-1]+' '+IntToStr(m));
          m:=1;
        end;
        Application.ProcessMessages ;
        if CheckBox1 .Checked then //允许要循环中退出
          Break;
      end;
      if (m>=8)and(m<=10) then  检查最一个值
        Memo1 .Lines .Add(FStringList.Strings [i-1]+' '+IntToStr(m));
    end;
      

  10.   

    在加载文件和进行排序时速度比较慢,
    用 ahjoe(强哥) 的程序生成的数据一个80MB的文件,用了两分钟才排序好。
    然后就是循环检查了。
      

  11.   

    你的意思是不是这样,如果给定条件为8-10,则在所有文件中的查找号码,将出现次数为>=8,<=10的号码找出来??
    是这个意思,多谢指教,我用强哥的方法,已经达到要求了。
    你的方法是不是更快,我试一下再说。