找top 10信息
来源:互联网 发布:成都多益网络怎么样 编辑:程序博客网 时间:2024/06/05 10:58
本文章内容来源于《程序员面试宝典》。
题目:
有1千万条短信,以文本文件的形式保存,一行一条,有重复。请用5分钟时间,找出重复出现最多的前10条。
解析:
某些面试者想用数据库的办法来实现:首先将文本导入数据库,再利用select语句某些方法得出前10条短信。但实际上用数据库是满足不了5分钟解决这个条件的。这是因为1千万条短信即使1秒钟录入1万条(这已经算是很快的数据录入了)5分钟才300万条。即使真的能在5分钟内录入完1千万条,也必须先建索引,不然sql语句5分钟内肯定得不出结果。但对1千万条记录建索引即使在5分钟之内都不可能完成的。所以用数据库的办法是不行的。类似题目是如何根据关键词搜索访问最多的前10个网站。
思路:
hash表法:可以用哈希表的方法对1千万条分成若干组进行边扫描边建散列表。第一次扫描,取首字节,尾字节,中间随便两字节作为Hash Code,插入到hash table中。并记录其地址和信息长度和重复次数,1千万条信息,记录这几个信息还放得下。同Hash Code且等长就疑似相同,比较一下。相同记录只加1次进hash table,但将重复次数加1。一次扫描以后,已经记录各自的重复次数,进行第二次hash table的处理。用线性时间选择可在O(n)的级别上完成前10条的寻找。分组后每份中的top10必须保证各不相同,可hash来保证,也可直接按hash值的大小来分类。
排序法:可以采用从小到大排序的方法,根据经验,除非是群发的过节短信,否则字数越少的短信出现重复的几率越高。建议从字数少的短信开始找起,比如一开始搜一个字的短信,找出重复出现的top10并分别记录出现次数,然后搜两个字的,依次类推。对于对相同字数的比较长的短信的搜索,除了hash之类的算法外,可以选择只抽取头、中和尾等几个位置的字符进行粗判,因为此种判断方式是为了加快查找速度但未能得到真正期望的top10,因此需要做标记;如此搜索一遍后,可以从各次top10结果中找到备选的top10,如果这top10中有刚才做过标记的,则对其对应字数的所有短信进行精确搜索以找到真正的top10并再次比较。
内存映射的方法:首先1千万条短信按现在的短信长度将不会超过1G空间,使用内存映射文件比较合适。可以一次映射(当然如果更大的数据量的话,可以采用分段映射),由于不需要频繁使用文件I/O和频繁分配小内存,这将大大提高数据的加载速度。其次,对每条短信的第i(i从0到70)个字母按ASCII码进行分组,其实也就是创建树。i是树的深度,也是短信第i个字母。该问题主要是解决两方面的内容,一是内容加载,二是短信内容比较。采用文件内存映射技术可以解决内容加载的性能问题(不仅仅不需要调用文件I/O函数,而且也不需要每读出一条短信都分配一小块内存),而使用树技术可以有效减少比较的次数。
代码如下:
struct TNode{ BYTE *pText; //直接指向文件映射的内存地址 DWORD dwCount; //计算器,记录此节点的相同短信数 TNode *ChildNodes[256]; //子节点数据,由于一个字母的ASCII值不可能超过256,所以子节点也不可能超过256 TNode() { //初始化成员 } ~TNode() { //释放资源 }}; //int nIndex是字母下标void CreateChilsNode(TNode *pNode,const BYTE* pText,int nIndex){ if(pNode->ChildNodes[pText[nIndex]]==NULL) { //如果不存在此子节点,就创建.TNode构造函数应该有初始化代码 //为了处理方便,这里也可以在创建的同时把此节点加到一个数组中 pNode->ChildNodes[pText[nIndex]]=new TNode; } if(pText[nIndex+1]=='\0') { //此短信已完成,计数器加1,并保存此短信内容 pNode->ChildNodes[pText[nIndex]]->dwCount++; pNode->ChildNodes[pText[nIndex]]->pText=pText; } else //if(pText[nText]!='\0') { //如果还未结束,就创建下一级节点 CreateNode(pNode->ChildNodes[pText[nIndex]],pText,nText+1); }}//创建根节点,pTexts是短信数组,dwCount是短信数量(这里是1千万)void CreateRootNode(const BYTE **pTexts,DWOED dwCount){ TNode RootNode; for(DWORD dwIndex=0;dwIndex<dwCount;dwIndex++) { CreateNode(&RootN,pTexts[dwIndex],0); } //所有节点按dwCount的值进行排序 //取前10个节点,显示结果}
1 0
- 找top 10信息
- 国内分类信息网站Top 10
- top信息含义
- mysql group by 按组返回 top 10 信息
- linux top-统计信息区
- top命令展示的信息
- popen + top 获取系统信息
- FindWindow只能找顶层窗口(top-level)
- TOP命令查看CPU信息详解
- top命令是什么?输出的信息是什么意思?
- 收集进程信息ps top kill
- top 执行一次、显示所有进程信息
- linux脚本后台记录top命令信息
- python 调用top命令获取输出信息
- Linux中top显示的信息详解
- top 执行一次、显示所有进程信息
- 广州怎么找富婆包养信息+q303100177
- 韶关怎么找富婆包养信息+q303100177
- ios开发-OC面向对象的三个特性-封装方法
- Q5
- java基础之 线程
- Linux无法登录,显示module is unknown
- codeblocks gcc error: 'for' loop initial declarations are only allowed in C99 mode|
- 找top 10信息
- Q6
- 2015广工网络赛初赛-Problem G: 漂洋过海来看你-迪杰斯特拉
- JS表格分页组件:fupage的设计思路和具体用法(未来考虑开源,争取在2015年)
- js中的async模块详解
- 设计模式之命令模式——管理智能家电
- BASE64、MD5、SHA
- sgu 136
- Sprite 3D用法和相关特性详解