搜索引擎的日志要记录所有查询串。
假设有一千万条查询,但不重复的不超过三百万条,现要统计最热门的10条查询串。
注:内存<1G,字符串长为0-255。请写出主要解决思路,并分析算法复杂度。

解决方案 »

  1.   

    select
    distinct Recorder ,
    '重复记录'= ( A.Recorder ),
    '所占数量' = ( select count(*) from Table where Recorder = A.Recorder )from Table A
    order by '所占数量' desc
      

  2.   

    然后再建一个虚表,取top 10就可以了,建议写成存储过程来处理,
      

  3.   

    先循环将1千万条数据汇总变成三百万条以下数据。并在循环过程中将每一条出现的次数统计出来。
    因为三百万数据量所占用空间为:3,000,000*255=765000000字节=729.56085205078125M。说明在内存中能够放下。
    在内存中建立一个具有两个字段的DataTable,分别放置这300,0000个查询,和查询出现的次数。下一步,找出这3,000,000条数据中出现最多的前十条查询。
    就是做一个有十行数据的DataTable,先把前十条数据保存到此DataTable中,然后做排序,后边的只要有比第十名查询次数多就把第十名挤出去。然后和第九名比,依次类推。
    好像叫做冒泡循环。此方式复杂程度低,效率也低。要对一千万数据循环一遍,三百万数据循环一遍,十条数据,循环上百万遍。
    如果用矩阵我想应当可以提高效率,但是用矩阵实现麻烦,我也不熟悉,就懒得查资料了。有兴趣的朋友可以补充进来。
      

  4.   

    chsl918(Stroy Book)说:
    “先循环将1千万条数据汇总变成三百万条以下数据。并在循环过程中将每一条出现的次数统计出来。”具体怎么实现呢?也用SQL吗?那还不如象abandonship(eagles of wind)那样直接order一下?
      

  5.   

    用循环汇总实现。
    DataTable dt一千万;
    //将一千万查询项目保存到dt一千万中DataTable dt三百万=new DataTable();
    //初始化dt三百万具有“数据”和“出现次数”字段。
    for (long i;i<dt一千万.Row.Count;i++)
    {
        DataView dv=new (dt三百万,"数据="+dt一千万.Row[i]["数据"].Tostring(),null,CurrentRows);
        if (dv.count!=0)
        {
            //向dt三百万中添加数据,将出现次数置为1
        }
        else
        {
            //将dt三百万中相应的出现次数加一
        }
    }虽然用程序实现确实麻烦了一些,但实际上数据库中也是用类似算法实现的。不过数据库因为程序作的底层,运行效率比较高。而且此功能封装好了,我用distinct等参数可以调用这些功能。