`
guoyunsky
  • 浏览: 854012 次
  • 性别: Icon_minigender_1
  • 来自: 上海
博客专栏
3d3a22a0-f00f-3227-8d03-d2bbe672af75
Heritrix源码分析
浏览量:206200
Group-logo
SQL的MapReduce...
浏览量:0
社区版块
存档分类
最新评论

Lucene3.0源码分析(二) Lucene中获得评分前N的DocumentID算法

阅读更多

       本博客属原创文章,欢迎转载!转载请务必注明出处:http://guoyunsky.iteye.com/blog/723963

      欢迎加入Heritrix群(QQ):109148319

      通过Lucene搜索返回的是评分(Score)前N的结果,默认是前100.这里我将这段算法复制下来,具体请看注释,同时这段算法不依赖Lucene任何组件,可以直接运行。

 

/**
 * 在一对数中找出前N个大的数,采用二叉堆
 * 模仿Lucene中的获得评分前N的DocumentID
 * 
 * @author Administrator
 *
 */
public class LuceneFindTopN {
	private int[] heap; 	//存储数据
	private int size;		//已存数据个数,也代表指针位置
	private int maxSize;	//取前maxSize大的数
	private int minElement;	//数据中最小的元素

	
	public LuceneFindTopN(int maxSize) {
		super();
		this.maxSize = maxSize;
		heap=new int[maxSize+1];
		size=0;
		minElement=0;
	}
	/**
	 * 插入数据
	 * @param element
	 * @return
	 */
	public boolean insert(int element){
		if(size<maxSize){
			put(element);
			return true;
		}else if(size>0&&element>top()){ //大于最小的元素才进入,并调整数据顺序
			heap[1]=element;	//替换头部元素(也就是最小的元素)为当前元素(因为当前元素比头部元素大)
			adjustTop();	//调整头部元素
			return true;
		}else{
			return false;
		}
	}
	/**
	 * 存入数据
	 * @param element
	 */
	public void put(int element){
		size++;
		heap[size]=element;
		upheap();
	}
	/**
	 * 返回top
	 * @return
	 */
	public int top(){
		if(size>0){
			return heap[1];
		}else{
			return 0;
		}
	}
	
	
	public int getSize() {
		return size;
	}

	public void setSize(int size) {
		this.size = size;
	}

	public final void upheap(){
		int i=size;
		int node=heap[i];
		int j=i>>>1;			//父节点位置
		
		while(j>0&&node<heap[j]){	//有父节点,并且要插入的数据比父节点的数据要小,则要交换位置
			heap[i]=heap[j];	//该节点等于父节点数据
			i=j;				//父节点指针位置
			j=j>>>1;			//迭代父节点的父节点,以此类推
		}
		heap[i]=node;			//要插入的数据放入合适位置
	}
	
	/**
	 * 排放数据,从最小的元素开始排放,会删除该元素
	 * @return
	 */
	public int pop(){
		if(size>0){
			int result=heap[1];	//第一个元素作为结果返回,因为第一个元素最小
			heap[1]=heap[size];	//第一个元素置为最大的元素
			heap[size]=-1;		//最大的元素清空
			size--;				//指针前移
			downHeap();
			return result;
		}else{
			return -1;
		}
	}
	
	public final void adjustTop(){
		downHeap();
	}
	public void downHeap(){
		int i = 1;
		int node = heap[i]; 	// 第一个元素,也就是刚插入的元素
		int j = i << 1; 		// 第二个元素
		int k = j + 1;			// 第三个元素		
		if (k <= size && heap[k]<heap[j]) { //如果当前数据大于等于3个,并且第三个数据小于第二个数据,则从第三个元素开始循环调整顺序,否则从第二个元素开始循环调整排序,如此可以少排一个并且可以扩容一倍
			j = k;
		}
		while (j <= size && heap[j]<node) {	//一直循环,直到超出size(也就是数组大小)并且小于要插入的节点
			heap[i] = heap[j]; // 置换
			i = j;
			j = i << 1; //再乘以2(扩容一倍)
			k = j + 1;  
			if (k <= size && heap[k]<heap[j]) { //没有超过size并且扩容一倍的数大于扩容一倍+1的数(也就是这2个数没有按照从小到大排序),则从扩容点开始又重新计算
				j = k;	//从扩容点
			}
		}
		heap[i] = node;  //将最后一个调整顺序的数据的位置为要插入的数据的合适位置
		
	}
	
	public void print(){
		for(int i=1;i<=maxSize;i++){
			System.out.println(heap[i]);
		}
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		LuceneFindTopN find=new LuceneFindTopN(3);
		int[] source={44,65,23,45,55,78,21,32,43,876,1,66,13,35,38,96,437,55,980,21,1010,1001,1334,42,2354,7788,344,333,557,5454,7664,1235};
		for(int i=0;i<source.length;i++){
			/*int a=(int)(Math.random()*1000);*/
			int a=source[i];
			System.out.println(find.insert(a)+":"+a);
		}
		
		System.out.println("================================");
		/*find.print();*/
		int max=find.getSize();
		for(int i=0;i<max;i++){
			System.out.println(find.pop());
		}
	}

}

 

更多技术文章、感悟、分享、勾搭,请用微信扫描:

分享到:
评论
1 楼 linliangyi2007 2010-11-11  
这个算法我是琢磨了一阵子了,发现它是一个不完全(非严格)的2叉树排序。

刚开始一直纠结于它对放入的数的排序不是严格的,每次都是半棵树的估算,后来才发现,pop的时候,每次都要沿着最短路径再取一个最小值,似乎明白了它的意义,upheap和downheap各管半棵树,真绝

相关推荐

    lucene3源码分析

    ### Lucene3源码分析知识点概述 #### 一、全文检索的基本原理 ##### 1. 总论 全文检索系统是一种高效的信息检索技术,能够帮助用户在海量文档中快速找到包含特定关键词的信息。Lucene是Java领域内最受欢迎的全文...

    lucene3.0庖丁+索引搜索程序

    通过分析这些示例,读者可以了解到如何在实际项目中应用Lucene3.0。 总结,Lucene3.0是Java世界中不可或缺的全文检索工具,它的索引构建、查询处理和结果排序机制为我们提供了高效且灵活的搜索功能。通过深入学习其...

    Lucene3.0_pdf

    通过《Lucene3.0原理与代码分析》的学习,读者可以掌握如何利用Lucene构建自己的全文搜索引擎,理解其高效检索背后的算法和技术,并能根据实际需求定制和优化索引和查询流程。尽管本文档基于3.0版本,但Lucene的基本...

    lucene3.5源码

    深入研究Lucene 3.5源码,有助于理解其内部工作机制,包括索引结构的实现、查询解析的逻辑以及搜索算法的细节。通过阅读源码,开发者可以定制自己的Analyzer、QueryParser,甚至优化Lucene的整体性能。 总结,...

    Lucene.net 2.0源码

    4. **评分机制**:Lucene 使用TF-IDF(词频-逆文档频率)算法来计算文档与查询的相关性,得分高的文档优先显示。此外,还可以通过自定义评分函数来优化搜索结果。 5. **更新与删除**:Lucene.NET 2.0 支持对已索引...

    基于Lucene索引的分析与实现

    搜索时,用户输入的查询会被转换成词项列表,然后Lucene会查找这些词项在索引中的对应信息,通过评分算法确定相关性,最终返回最相关的文档。 在实现过程中,需要关注的关键步骤包括: - 文档解析:将非结构化的...

    Lucene项目源码

    Lucene的评分机制基于TF-IDF(Term Frequency-Inverse Document Frequency),它衡量一个词在文档中的重要性。`Similarity`接口定义了计算相关性的算法,可以自定义以适应不同的应用场景。 6. **内存与磁盘缓存** ...

    Lucene索引搜索简介以及入门实例源码.rar

    4. **分析器(Analyzer)**:在建立索引前,Lucene会使用分析器对文本进行处理,如分词、去除停用词等,以便更好地匹配用户的查询。 5. **查询(Query)**:用户输入的搜索词经过分析后转换为查询对象,Lucene使用...

    luceneInAction2nd源码

    通过《Lucene in Action》第二版的学习和源码的实践,我们可以深刻理解Lucene的工作原理及其背后的算法逻辑。对于希望深入研究搜索引擎技术的开发者来说,这本书和其中的源码都是不可多得的宝贵资源。通过对这些知识...

    lucene.net1.4.3全文检索源文件

    4. 搜索(Searching):Lucene.NET使用评分系统(Scoring)来衡量文档与查询的相关性,返回最相关的文档结果。 三、主要组件 1. 文档(Document):代表要被搜索的信息单元,可以包含多个字段(Field),如标题、...

    lucene站内搜索

    4. **评分(Scoring)**: Lucene使用TF-IDF(Term Frequency-Inverse Document Frequency)算法计算每个匹配文档的相关性分数。 5. **结果排序(Resuliting Sorting)**: 按照评分从高到低排序搜索结果,返回给用户...

    Lucene 索引的简单使用

    - **评分和排序**:Lucene使用TF-IDF算法计算文档与查询的相关性,用于确定搜索结果的排序。 - **更新和删除**:使用IndexWriter可以更新已有文档,或通过ID删除文档。 - **多线程索引**:通过控制IndexWriter的...

    基于LUCENE的搜索引擎的设计与实现源代码

    2. 相关性评分:LUCENE使用TF-IDF(Term Frequency-Inverse Document Frequency)算法计算文档与查询的相关性,得分越高,表示文档与查询匹配度越高。 3. 搜索执行:通过Query对象和索引进行匹配,找到满足条件的...

    全文搜索-Lucene

    1. **索引创建**:使用 Analyzer 分析文档内容,创建 Document 对象,然后通过 IndexWriter 添加到索引中。 2. **索引优化**:合并多个段(Segment)以减少索引碎片,提高查询效率。 3. **查询执行**:使用 ...

    lucene-core-2.4.0的源码

    1. **Document**:Lucene中的基本信息单元是Document,它由多个字段(Field)组成,每个字段存储不同类型的数据。 2. **IndexWriter**:负责创建和更新索引,它处理文档的添加、删除和修改。在Lucene 2.4.0中,...

Global site tag (gtag.js) - Google Analytics