搜索引擎热门查询统计

题目描述:
    搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的长度为1-255字节。
    假设目前有一千万个记录(这些查询串的重复度比较高,虽然总数是1千万,但如果除去重复后,不超过3百万个。一个查询串的重复度越高,说明查询它的用户越多,也就是越热门。),请你统计最热门的10个查询串,要求使用的内存不能超过1G。

分析:

这个问题在之前的这篇文章十一、从头到尾彻底解析Hash表算法里,已经有所解答。方法是:

第一步、先对这批海量数据预处理,在O(N)的时间内用Hash表完成统计
    第二步、借助堆这个数据结构,找出Top K,时间复杂度为N‘logK。
        即,借助堆结构,我们可以在log量级的时间内查找和调整/移动。因此,维护一个K(该题目中是10)大小的小根堆(K1>K2>....Kmin,Kmin设为堆顶元素),然后遍历300万的Query,分别和根元素Kmin进行对比比较(如上第2节思路3所述,若X>Kmin,则更新并调整堆,否则,不更新),我们最终的时间复杂度是:O(N) + N'*O(logK),(N为1000万,N’为300万)。更多详情请参考原文。

代码实现:

#include <stdio.h>
#include <stdlib.h> #define MAXLEN 100005
#define K 100 void Swap(int* a, int* b) {
*a=*a^*b;
*b=*b^*a;
*a=*a^*b;
} void HeapAdjust(int array[], int i, int length) {
int child, temp;
for(temp = array[i]; *i+<length; i=child) {
child = *i+;
if(child < length- && array[child+] < array[child])
child++;
if (temp > array[child])
array[i] = array[child];
array[child] = temp;
}
} int GetMin(int array[], int length, int k) {
int min = array[];
Swap(&array[], &array[length-]); int child, temp;
int i=, j=k-;
for (temp = array[]; j> && *i+<length; --j,i=child) {
child = * i + ;
if (child < length - && array[child+] < array[child])
child++;
if (temp > array[child])
array[i] = array[child];
else
break;
array[child] = temp;
}
return min;
} void Kmin(int array[] , int length , int k) {
for(int i=length/-;i>=;--i)
//初始建堆,时间复杂度为O(n)
HeapAdjust(array,i,length); int j=length;
//k次循环,每次循环的复杂度最多为k次交换,复杂度为o(k^2)
for(int i=k;i>;--i,--j){
int min=GetMin(array,j,i);
printf("%d,", min);
}
} int main() {
int array[MAXLEN];
for(int i=MAXLEN; i>; --i) { // init array
array[MAXLEN - i] = i;
}
Kmin(array, MAXLEN, K);
return ;
}

ref: http://blog.csdn.net/v_JULY_v/article/details/6256463

http://blog.csdn.net/v_JULY_v/article/details/6403777

topK 算法的更多相关文章

  1. 关于堆排序和topK算法的PHP实现

    问题描述 topK算法,简而言之,就是求n个数据里的前m大个数据,一般而言,m<<n,也就是说,n可能有几千万,而m只是10或者20这样的两位数. 思路 最简单的思路,当然是使用要先对这n ...

  2. java TopK算法

    现有一亿个数据,要求从其中找出最小的一万个数,希望所需的时间和空间最小,也就是所谓的topK问题 TopK问题就是从海量的数据中取最大(或最小的)的K个数. TopK问题其实是有线性时间复杂度的解的, ...

  3. (转)基于快速排序的TOPK算法

    基于快速排序的TOPK算法 转自:http://blog.csdn.net/fanzitao/article/details/7617223 思想: 类似于快速排序,首先选择一个划分元,如果这个划分元 ...

  4. topk算法

    方法一 堆排序 自建堆 heapMax方法,从上至下调整堆 pop时,可以使用自上而下调整堆,调用heapMax(arr,0,sz-1); push时,需要自下到上调整即 从上到下调整: void h ...

  5. Python 实现转堆排序算法原理及时间复杂度(多图解释)

    原创文章出自公众号:「码农富哥」,欢迎转载和关注,如转载请注明出处! 堆基本概念 堆排序是一个很重要的排序算法,它是高效率的排序算法,复杂度是O(nlogn),堆排序不仅是面试进场考的重点,而且在很多 ...

  6. 大数据热点问题TOP K

    1单节点上的topK (1)批量数据 数据结构:HashMap, PriorityQueue 步骤:(1)数据预处理:遍历整个数据集,hash表记录词频 (2)构建最小堆:最小堆只存k个数据. 时间复 ...

  7. 大数据计算:如何仅用1.5KB内存为十亿对象计数

    大数据计算:如何仅用1.5KB内存为十亿对象计数  Big Data Counting: How To Count A Billion Distinct Objects Using Only 1.5K ...

  8. HashTable和HashSet中的类型陷阱

    HashTable和HashSet中的类型陷阱 发现这个陷阱的起因是这样的:我现在有上百万字符串,我准备用TopK算法统计出出现次数做多的前100个字符串. 首先我用Hashtable统计出了每个字符 ...

  9. sdn测量论文简介

    Prelude: Ensuring Inter-Domain Loop-Freedom in SDN-Enabled Networks 来源:APNet: The Asia-Pacific Works ...

随机推荐

  1. Windows下搭建Android NDK开发环境及命令行编译

    首先说明本文内的相关安装操作参考<Pro Android C++ with the NDK>一书. 安装 Windows搭建Android NDK开发环境需要安装如下部分(同时需要配置对应 ...

  2. 有了#ifdef 为什么还需要#if defined

    有了#ifdef 为什么还需要#if  defined ? #include <stdio.h> #define A #define B void test(int a,int b) { ...

  3. kylin的状态栏(启动器)改成ubuntu之前的样子

    ylin的状态栏(启动器)改成ubuntu之前的样子,ubuntu是在左边的,kylin在底部.占空间. 执行命令 gsettings set com.canonical.Unity.Launcher ...

  4. delphi判断线程是否正在运行

    相关资料:http://www.delphitop.com/html/xiancheng/376.html unit Unit1; interface uses Winapi.Windows, Win ...

  5. [转] [Java] 知乎下巴第5集:使用HttpClient工具包和宽度爬虫

    原文地址:http://blog.csdn.net/pleasecallmewhy/article/details/18010015 下载地址:https://code.csdn.net/wxg694 ...

  6. JAVA字符串怎么转换成整数

    首先你要确定你的字符串可以转换为int类型的,比如说: String s = "123"; 如果String s = "abc";则转换时会报错! 需要的包是& ...

  7. Tomcat性能优化(二) ExpiresFilter设置浏览器缓存

    Tomcat性能调优 通过ExpiresFilter设置资源缓存 [官方文档] http://tomcat.apache.org/tomcat-7.0-doc/config/filter.html#E ...

  8. mysq在某一刻同时获取主从库的位置点

    在从库进行锁表操作flush table with read lock, 通过show slave status\G 获取对应主库的位置点: show slave status\G********** ...

  9. go channel例子

    channel初步认识: package main import "fmt" import "time" func main() { c := make(cha ...

  10. MATLAB — axis

    转至:http://blog.csdn.net/cs_zlg/article/details/8516463 axis中文为“轴”之意,在matlab中用于控制坐标轴的范围和样式(颜色等). axis ...