如何从每个单独行中包含sessionId和PageId组合列表的大日志文件中查找特定用户的访问页面?
文件太大,内存无法容纳。它的意思是找出在同一会话(用户)中访问量最大的页面。
例如
我的文件是(顺序是sessionId,PageID)
usera page1
userb page2
userb page1
usera page3
....
它应该会打印出来
usera visits page1 most followed by page3.
如果访问的页面数量相等,则由您决定如何处理这种情况(可以打印两者,也可以打印其中任何一个)
您将使用哪种数据结构/算法进行此操作?由于这是一个面试问题,因此需要高效的算法/数据结构。面试官没有具体说明他正在寻找的算法顺序。
我想出了std::map<string,std::pair<string,int> >
解决方案。面试官问我是否可以做得比这更好,或者如果键集太大,map不能有效地处理,应该怎么做?
发布于 2011-10-09 13:18:31
我认为第一步应该是删除所有“非usera”行,因为您正在进行按用户解析。这将是将所有用户分成不同文件的一次性作业。在此之后,您可以进行逐行分析,在“历史”中只保留几行。您可以使用简单的行解析器来完成此操作,而不必将整个文件存储在内存中。
如果它必须需要某种数据结构,那么您可能需要考虑map-reduce范例-- Hadoop对于10 on以上的文件来说将是理想选择。
发布于 2011-10-09 13:32:47
对我来说,我看到的关键字是:same session。在这种情况下,我们需要做的不是读取整个日志文件,而是尝试猜测这个特定的会话。
我们需要记住,会话将在特定的时间段内处于活动状态。定时由服务器设置,例如20分钟。因此,在我们找出用户何时登录之后,我们需要做的是获取指向文件中用户何时注销或最后一次活动会话的特定位置的指针。
发布于 2011-10-10 01:58:55
您可以首先考虑使用外部排序对文件进行排序(将文件拆分成适合内存的块,然后对每个块进行排序并将其合并回去)您可以将排序的文件再次拆分成相同数量的块,但要跟踪每个块对应的范围。这样,就可以执行二进制搜索来查找相关的块,加载它并搜索任何用户。
因为它是一个排序文件,所以相似的用户条目将是连续的,实际上,人们还可以在合并块的过程中计算出现的次数,并将附加到该行的值写入,以供以后使用。
https://stackoverflow.com/questions/7701577
复制相似问题