topk代码

1、生成随机数代码:

  1. package test;  
  2.   
  3.   
  4. import java.util.Random;  
  5.   
  6.   
  7. public class RandomTest {  
  8.      public static void main(String[] args){          
  9.          int number=0;  
  10.          for (int i = 0; i < 100000; i++) {  
  11.               number = new Random().nextInt(100000) + 1;  
  12.              System.out.println(number);  
  13.         }  
  14.     }  
  15. }  



2、生成部分数据如下所示:
  1. [hadoop@hadoop ~]$ tail -10 top_k.txt  
  2. 16287  
  3. 86786  
  4. 63942  
  5. 5960  
  6. 87524  
  7. 53898  
  8. 81409  
  9. 92020  
  10. 68327  
  11. 92706  
  12. [hadoop@hadoop ~]$  



3、代码:
  1. package test;  
  2.   
  3.   
  4. import java.io.IOException;  
  5. import java.util.TreeMap;  
  6. import org.apache.hadoop.conf.Configuration;  
  7. import org.apache.hadoop.fs.Path;  
  8. import org.apache.hadoop.io.LongWritable;  
  9. import org.apache.hadoop.io.NullWritable;  
  10. import org.apache.hadoop.io.Text;  
  11. import org.apache.hadoop.mapreduce.Job;  
  12. import org.apache.hadoop.mapreduce.Mapper;  
  13. import org.apache.hadoop.mapreduce.Reducer;  
  14. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;  
  15. import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;  
  16. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;  
  17. import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;  
  18.   
  19.   
  20. public class Topk {  
  21. /** 
  22. * map方法 
  23. */  
  24. private static final int k=10;  
  25. public static class MyMapper extends Mapper<LongWritable, Text, LongWritable, Text>{   
  26. LongWritable lw=new LongWritable();  
  27. Text text=new Text();  
  28. TreeMap<Long, String > treemap_mapper=new TreeMap<Long, String>();  
  29. @Override  
  30. protected void map(LongWritable key, Text value,Context context)  
  31. throws IOException, InterruptedException {  
  32. String line=value.toString();  
  33. String[] splited=line.split("\t");  
  34.   
  35. treemap_mapper.put(Long.parseLong(splited[0]), line);  
  36.   
  37. if(treemap_mapper.size()>k){  
  38. treemap_mapper.remove(treemap_mapper.firstKey());  
  39. }  
  40.   
  41. }  
  42.   
  43. @Override  
  44. protected void cleanup(Context context)  
  45. throws IOException, InterruptedException {  
  46.   
  47. for (Long numLong : treemap_mapper.keySet()) {  
  48. context.write(new LongWritable(numLong), new Text(treemap_mapper.get(numLong)));  
  49. }  
  50. }  
  51.   
  52. }  
  53.   
  54. /** 
  55. * reducer方法 
  56. * @author Administrator 
  57. * 
  58. */  
  59. public static class MyReducer extends Reducer<LongWritable, Text, LongWritable, NullWritable>{  
  60. TreeMap<Long, String> treemap_reducer=new TreeMap<Long, String>();  
  61. @Override  
  62. protected void reduce(LongWritable k2,Iterable<Text> v2s,Context context)  
  63. throws IOException, InterruptedException {  
  64. treemap_reducer.put(k2.get(), v2s.iterator().next().toString());  
  65.   
  66. if(treemap_reducer.size()>k){   
  67. treemap_reducer.remove(treemap_reducer.firstKey());  
  68. }  
  69. }  
  70.   
  71. @Override  
  72. protected void cleanup(Context context)  
  73. throws IOException, InterruptedException {  
  74. Long[] outLong=new Long[10];  
  75. int flag=0;  
  76. for (Long numLong : treemap_reducer.keySet()) {  
  77. outLong[flag]=numLong;  
  78. flag++;  
  79. }  
  80.   
  81. for (int i=k-1;i>=0;i--) {  
  82. context.write(new LongWritable(outLong[i]),NullWritable.get());  
  83. }  
  84. }  
  85.   
  86. }  
  87. /** 
  88. * 主方法 
  89. * @param args 
  90. * @throws Exception 
  91. */  
  92. public static void main(String[] args) throws Exception {  
  93. Configuration conf = new Configuration();  
  94. Job job=Job.getInstance(conf, Topk.class.getSimpleName());  
  95. job.setJarByClass(Topk.class);  
  96.   
  97. job.setNumReduceTasks(1);  
  98.   
  99. job.setMapperClass(MyMapper.class);  
  100. job.setReducerClass(MyReducer.class);  
  101.   
  102. job.setMapOutputKeyClass(LongWritable.class);  
  103. job.setMapOutputValueClass(Text.class);  
  104.   
  105. job.setOutputKeyClass(LongWritable.class);  
  106. job.setOutputValueClass(NullWritable.class);  
  107.   
  108. job.setInputFormatClass(TextInputFormat.class);  
  109. job.setOutputFormatClass(TextOutputFormat.class);  
  110.   
  111. FileInputFormat.setInputPaths(job, args[0]);  
  112. FileOutputFormat.setOutputPath(job, new Path(args[1]));  
  113.   
  114. job.waitForCompletion(true);  
  115.   
  116. }  
  117. }  




4、代码运行后输出在HDFS上面的目录:
  1. [hadoop@hadoop ~]$ hdfs dfs -ls /user/hadoop/output_topk/output3  
  2. Found 2 items  
  3. -rw-r--r--   3 hadoop supergroup          0 2015-08-30 21:09 /user/hadoop/output_topk/output3/_SUCCESS  
  4. -rw-r--r--   3 hadoop supergroup         80 2015-08-30 21:09 /user/hadoop/output_topk/output3/part-r-00000  



5、查看top10的数据:
  1. [hadoop@hadoop ~]$ hdfs dfs -text /user/hadoop/output_topk/output3/part-r-00000  
  2. 9999706  
  3. 9999594  
  4. 9999424  
  5. 9999199  
  6. 9997208  
  7. 9996513  
  8. 9995640  
  9. 9995515  
  10. 9993977  
  11. 9991946 
### C语言 TopK 算法实现 #### 使用快速选择算法 一种高效的方法来找到数组中的第 K 大元素是通过修改后的快速排序方法,即所谓的快速选择算法。这种方法平均情况下具有 O(n) 的时间复杂度。 ```c #include <stdio.h> #include <stdlib.h> int partition(int* nums, int low, int high) { int pivot = nums[high]; int i = low; for (int j = low; j < high; ++j) { if (nums[j] >= pivot) { // 寻找较大的数放在左边 int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; i++; } } int temp = nums[i]; nums[i] = nums[high]; nums[high] = temp; return i; } int findKthLargest(int* nums, int start, int end, int k) { if (start <= end) { int pIndex = partition(nums, start, end); if (pIndex == k - 1) return nums[pIndex]; else if (pIndex > k - 1) return findKthLargest(nums, start, pIndex - 1, k); else return findKthLargest(nums, pIndex + 1, end, k); } return -1; } ``` 这段代码实现了寻找给定整型数组 `nums` 中的第 K 大元素的功能[^1]。 #### 利用最小堆求解 Top-K 问题 另一种常见的策略是构建一个大小固定为 K 的最小堆。当遍历到新元素时,如果该元素大于当前堆顶,则替换掉堆顶并重新调整堆;最终得到的就是前 K 大的元素集合。此方法可以有效地降低空间开销,并且对于流式输入的数据特别有用。 ```c #define MAX_HEAP_SIZE 10000 typedef struct MinHeapNode_ { int value; } MinHeapNode; void min_heapify(MinHeapNode heap[], int idx, int size); // 插入节点至最小堆中 void insert_minheap(MinHeapNode heap[], int *size, int val){ (*size)++; int i = *size - 1; while ((i != 0) && (val < heap[(i-1)/2]; i = (i-1)/2; } heap[i].value = val; if(*size>MAX_HEAP_SIZE){ // 维持堆的最大容量不超过设定值 extractMin(heap,size); }else{ min_heapify(heap,*size-1,*size); } } // 提取最小堆中的根结点(即最小值) int extractMin(MinHeapNode heap[], int *size){ int rootValue = heap[0].value; heap[0]=heap[*size-1]; (*size)--; min_heapify(heap,0,*size); return rootValue; } // 调整最小堆以保持其性质 void min_heapify(MinHeapNode heap[], int idx, int size){ int smallest=idx,left=(2*idx)+1,right=(2*idx)+2; if((left<size)&&(heap[left].value<heap[idx].value)) smallest=left; if((right<size)&&(heap[right].value<heap[smallest].value)) smallest=right; if(smallest!=idx){ swap(&heap[idx],&heap[smallest]); min_heapify(heap,smallest,size); } } // 获取 top-k 结果集 void getTopKElements(const int arr[], int n, const int k, int result[]){ MinHeapNode h[MAX_HEAP_SIZE]; int heapSize = 0; for(int i=0;i<n;++i){ insert_minheap(h,&heapSize,arr[i]); } for(int i=k-1;i>=0;--i){ result[i]=extractMin(h,&heapSize); } } ``` 这里展示了如何利用最小堆来处理 Top-K 问题的具体过程[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值