简介
在搜索引擎中,如Lucene,搜索的结果是最相似 的前N条,那么如何从一个无序的数组中得到前N个最大(或最小)的值呢?以下是我写的一个Top-N的演示程序。主要用到的数据结构是TreeSet,TreeSet会自动化实现插入排序,前提是该类要实现Comparable接口。
实体类
/*
* $filename: Student.java,v $
* $Date: 2013-10-23 $
* Copyright (C) ZhengHaibo, Inc. All rights reserved.
* This software is Made by Zhenghaibo.
*/
package edu.njupt.zhb;
/*
*@author: ZhengHaibo
*web: http://blog.csdn.net/nuptboyzhb
*mail: zhb931706659@126.com
*2013-10-23 Nanjing,njupt,China
*/
public class Student implements Comparable<Student> {
private String name;
public Student(String name, int score) {
this.name = name;
this.score = score;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
private int score;
@Override
public int compareTo(Student o) {
// TODO Auto-generated method stub
if(o.getScore()>this.score){
return 1;
}else if(o.getScore()<this.score){
return -1;
}
return 0;
}
}
Demo
/*
* $filename: TopNTest.java,v $
* $Date: 2013-10-23 $
* Copyright (C) ZhengHaibo, Inc. All rights reserved.
* This software is Made by Zhenghaibo.
*/
package edu.njupt.zhb;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.TreeSet;
/*
*@author: ZhengHaibo
*web: http://blog.csdn.net/nuptboyzhb
*mail: zhb931706659@126.com
*2013-10-23 Nanjing,njupt,China
*/
public class TopNTest {
private TreeSet<Student> topN = new TreeSet<Student>();//Student必须实现Comparable接口
private List<Student> studentList = new ArrayList<Student>();
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
TopNTest test = new TopNTest();
test.initList();//随机初始化学生分数
test.topN(10);//获取前10个最高分
test.printTopN();
}
/**
* 打印TreeSet
*/
public void printTopN() {
// TODO Auto-generated method stub
System.out.println("--------------------topN result----------------");
int index = 0;
for(Student student:topN){
index++;
System.out.println("No:"+index+",name="+student.getName()+",score="+student.getScore());
}
}
/**
* 随机产生100个学生的分数,并初始化到studentList中
*/
public void initList(){
System.out.println("--------------------init----------------");
for(int i=0;i<1000;i++){
Random rand = new Random();
Student student = new Student("student"+i, rand.nextInt(100));
studentList.add(student);
//System.out.println("name = "+student.getName()+",score="+student.getScore());
}
}
/**
* 计算前N个最大的值
* @param N 返回前N个最大的值
*/
public void topN(int N){
int minScore = 110;
for(Student student:studentList){
if(minScore>100){//第一次运行
minScore = student.getScore();
}
if(topN.size()<N){//首先填满topN
topN.add(student);
if(student.getScore()<minScore){
minScore = student.getScore();//更新最低分
}
}else if(student.getScore()>minScore){//topN已经填满,并且该学生的分数比最低分高
topN.remove(topN.last());//先删除topN中的最低分
topN.add(student);
minScore = topN.last().getScore();//更新最低分
}
}
}
}
实验结果
由于初始化数据是随机产生的数字,所以每次运行的结果有所不同。