Top K算法问题的实现

  1. http://blog.csdn.net/v_july_v/article/details/6403777#comments
  2. //copyright@yansha &&July  
  3. //July、updated,2011.05.08  
  4.   
  5. //题目描述:  
  6. //搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的  
  7. //长度为1-255字节。假设目前有一千万个记录(这些查询串的重复度比较高,虽然总数是1千万,但如果  
  8. //除去重复后,不超过3百万个。一个查询串的重复度越高,说明查询它的用户越多,也就是越热门),  
  9. //请你统计最热门的10个查询串,要求使用的内存不能超过1G。  
  10.   
  11. #include <iostream>  
  12. #include <string>  
  13. #include <assert.h>  
  14. using namespace std;  
  15.   
  16. #define HASHLEN 2807303  
  17. #define WORDLEN 30  
  18.   
  19. // 结点指针  
  20. typedef struct node_no_space *ptr_no_space;  
  21. typedef struct node_has_space *ptr_has_space;  
  22. ptr_no_space head[HASHLEN];  
  23.   
  24. struct node_no_space   
  25. {  
  26.     char *word;  
  27.     int count;  
  28.     ptr_no_space next;  
  29. };  
  30.   
  31. struct node_has_space  
  32. {  
  33.     char word[WORDLEN];  
  34.     int count;  
  35.     ptr_has_space next;  
  36. };  
  37.   
  38. // 最简单hash函数  
  39. int hash_function(char const *p)  
  40. {  
  41.     int value = 0;  
  42.     while (*p != '/0')  
  43.     {  
  44.         value = value * 31 + *p++;  
  45.         if (value > HASHLEN)  
  46.             value = value % HASHLEN;  
  47.     }  
  48.     return value;  
  49. }  
  50.   
  51. // 添加单词到hash表  
  52. void append_word(char const *str)  
  53. {  
  54.     int index = hash_function(str);  
  55.     ptr_no_space p = head[index];  
  56.     while (p != NULL)  
  57.     {  
  58.         if (strcmp(str, p->word) == 0)  
  59.         {  
  60.             (p->count)++;  
  61.             return;  
  62.         }  
  63.         p = p->next;  
  64.     }  
  65.       
  66.     // 新建一个结点  
  67.     ptr_no_space q = new node_no_space;  
  68.     q->count = 1;  
  69.     q->word = new char [strlen(str)+1];  
  70.     strcpy(q->word, str);  
  71.     q->next = head[index];  
  72.     head[index] = q;  
  73. }  
  74.   
  75.   
  76. // 将单词处理结果写入文件  
  77. void write_to_file()  
  78. {  
  79.     FILE *fp = fopen("result.txt""w");  
  80.     assert(fp);  
  81.       
  82.     int i = 0;  
  83.     while (i < HASHLEN)  
  84.     {  
  85.         for (ptr_no_space p = head[i]; p != NULL; p = p->next)  
  86.             fprintf(fp, "%s  %d/n", p->word, p->count);  
  87.         i++;  
  88.     }  
  89.     fclose(fp);  
  90. }  
  91.   
  92. // 从上往下筛选,保持小根堆  
  93. void sift_down(node_has_space heap[], int i, int len)  
  94. {  
  95.     int min_index = -1;  
  96.     int left = 2 * i;  
  97.     int right = 2 * i + 1;  
  98.       
  99.     if (left <= len && heap[left].count < heap[i].count)  
  100.         min_index = left;  
  101.     else  
  102.         min_index = i;  
  103.       
  104.     if (right <= len && heap[right].count < heap[min_index].count)  
  105.         min_index = right;  
  106.       
  107.     if (min_index != i)  
  108.     {  
  109.         // 交换结点元素  
  110.         swap(heap[i].count, heap[min_index].count);  
  111.           
  112.         char buffer[WORDLEN];  
  113.         strcpy(buffer, heap[i].word);  
  114.         strcpy(heap[i].word, heap[min_index].word);  
  115.         strcpy(heap[min_index].word, buffer);  
  116.           
  117.         sift_down(heap, min_index, len);  
  118.     }  
  119. }  
  120.   
  121. // 建立小根堆  
  122. void build_min_heap(node_has_space heap[], int len)  
  123. {  
  124.     if (heap == NULL)  
  125.         return;  
  126.       
  127.     int index = len / 2;  
  128.     for (int i = index; i >= 1; i--)  
  129.         sift_down(heap, i, len);  
  130. }  
  131.   
  132. // 去除字符串前后符号  
  133. void handle_symbol(char *str, int n)  
  134. {  
  135.     while (str[n] < '0' || (str[n] > '9' && str[n] < 'A') || (str[n] > 'Z' && str[n] < 'a') || str[n] > 'z')  
  136.     {  
  137.         str[n] = '/0';  
  138.         n--;  
  139.     }  
  140.       
  141.     while (str[0] < '0' || (str[0] > '9' && str[0] < 'A') || (str[0] > 'Z' && str[0] < 'a') || str[0] > 'z')  
  142.     {  
  143.         int i = 0;  
  144.         while (i < n)  
  145.         {  
  146.             str[i] = str[i+1];  
  147.             i++;  
  148.         }  
  149.         str[i] = '/0';  
  150.         n--;  
  151.     }  
  152. }  
  153.   
  154. int main()  
  155. {  
  156.     char str[WORDLEN];  
  157.     for (int i = 0; i < HASHLEN; i++)  
  158.         head[i] = NULL;  
  159.       
  160.     // 将字符串用hash函数转换成一个整数并统计出现频率  
  161.     FILE *fp_passage = fopen("string.txt""r");  
  162.     assert(fp_passage);  
  163.     while (fscanf(fp_passage, "%s", str) != EOF)  
  164.     {  
  165.         int n = strlen(str) - 1;  
  166.         if (n > 0)  
  167.             handle_symbol(str, n);  
  168.         append_word(str);  
  169.     }  
  170.     fclose(fp_passage);  
  171.       
  172.     // 将统计结果输入文件  
  173.     write_to_file();  
  174.       
  175.     int n = 10;  
  176.     ptr_has_space heap = new node_has_space [n+1];  
  177.       
  178.     int c;  
  179.       
  180.     FILE *fp_word = fopen("result.txt""r");  
  181.     assert(fp_word);  
  182.     for (int j = 1; j <= n; j++)  
  183.     {  
  184.         fscanf(fp_word, "%s %d", &str, &c);  
  185.         heap[j].count = c;  
  186.         strcpy(heap[j].word, str);  
  187.     }  
  188.       
  189.     // 建立小根堆  
  190.     build_min_heap(heap, n);  
  191.       
  192.     // 查找出现频率最大的10个单词  
  193.     while (fscanf(fp_word, "%s %d", &str, &c) != EOF)  
  194.     {  
  195.         if (c > heap[1].count)  
  196.         {  
  197.             heap[1].count = c;  
  198.             strcpy(heap[1].word, str);  
  199.             sift_down(heap, 1, n);  
  200.         }  
  201.     }  
  202.     fclose(fp_word);  
  203.       
  204.     // 输出出现频率最大的单词  
  205.     for (int k = 1; k <= n; k++)  
  206.         cout << heap[k].count << " " << heap[k].word << endl;  
  207.       
  208.     return 0;  
  209. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值