Top-N算法的实现(Java版)

简介

在搜索引擎中,如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();//更新最低分
			}
		}
	}

}

实验结果

由于初始化数据是随机产生的数字,所以每次运行的结果有所不同。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值