如何从具有userID和pageID的大型日志文件中查找最常访问的3网页序列

时间:2011-11-19 16:54:18

标签: c++ c algorithm sorting map

给出访问的网页日志文件:

Userid  PageID
A          1
A          2
A          3
B          2
B          3
C          1
B          4
A          4

查找最常见的网页ID访问顺序:

 for A : 1-2-3, 2-3-4
 for B : 2-3-4

所以,2-3-4是最常见的。

我的想法:

  1. 将文件的每个项目放入map1<key:user_id, list<pageID> >
  2. list.size() == 3时,创建一个新的结构three_hits来保存三个pageID。
  3. 将其放入map2<struct three_hits, int counter>
  4. 然后,找到map2中具有最大计数器值的项目。
  5. 声明:

     struct three_hits
     {
         int f_page;
         int s_page;
         int t_page;  
     };
     map<string, list<int> > map_hit;
     map<struct three_hits, int> map_t_hits;
    

    扫描记录:

    for each( record: r in log)
    {
        if(map_hit.count(r.userid) >0) 
        {
            map_hit[r.uid].second.push_back(r.pageID);
    
            if(map_hit[r.uid].second.size() ==3)
            {
    
                list<int> tmp=map_hit[r.uid].second;
    
                t_hits(tmp[0],tmp[1],tmp[2]);
    
                // O(n lg n)
                if( map_t_hits.count(t_hits) >0)
                    map_t_hits[t_hits]++;
                else
                    map_t_hits[t_hits]=1;
            }
            else
            { 
                list<int> tmp(r.pageID);
    
                map_hit[r.uid]=tmp;
            }
        }
        // O(n)
    

    迭代map_t_hits一次,找到价值最高的密钥(t_hits)。

    地图的时间 O(n lg n)和空间 O(n)

    有更好的解决方案吗?

1 个答案:

答案 0 :(得分:0)

您可以考虑使用sort-merge执行此操作。首先使用用户id的稳定排序将给定用户的所有序列放在一起,保持原始顺序。然后对所有3个网页序列进行排序,最后计算相等序列的运行。这也是O(n log n)。它可能需要花费更多的时间在实践中,但如果使用内部存储器运行可能需要更少的存储,并且可以在外部存储器中运行,如果您在任何时候都有太多的数据存储。它是否真的更好取决于你的特定情况的细节。