`
zhangdp_neu
  • 浏览: 10667 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

五个Java类 揭秘 多关键字搜索 引擎

阅读更多
最近看了《数学之美系列五》-- 简单之美:布尔代数和搜索引擎的索引。

通过文章的介绍,了解了搜索引擎的原理,就动手尝试了一下。代码除了学习最基本原理外没有任何价值。所有的操作都是内存操作,与真实的商用搜索系统相差甚远。

首先创建一个索引器,这是最最简单的索引器。

package index;

import java.util.StringTokenizer;

import store.IndexMap;
import store.StoreMap;

/**
 * 建立文章倒排序的索引,一个最简单的索引器
 * @author zhangdp
 *
 */
public class SimpleIndex {

	/**
	 * 将value加入索引
	 * @param value
	 */
	public void index(int num,String value){
		//最简单的分词器
		StringTokenizer st = new StringTokenizer(value);
		while(st.hasMoreTokens()){
			String keyword =st.nextToken();
			IndexMap.index(keyword, num);
		}
	}
}



然后在创建一个存储系统,当然这个只是查找方便使用,也可以不用,直接用文件系统。
想相应的文章按编号索引
package store;

import java.util.HashMap;
import java.util.Map;

public class StoreMap {

	//key 为文章编号,Value 为文章内容
	private static Map<Integer,String> store = new HashMap<Integer,String>();
	
	public static  void put(Integer key,String value){
		store.put(key, value);
	}
	
	public static String get(Integer key){
		return store.get(key);
	}
}


然后创建最关键的部分了-索引
package store;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 倒排索引
 * @author zhangdp
 *
 */
public class IndexMap {

	/**
	 * 索引,key为关键字,value为文章列表向量,第i位的值为true表示
	 * 第i个文章中出现key这个关键词,否则没出现
	 * 
	 */
	private static Map<String,BitVector> indexMap = new HashMap<String,BitVector>();

	/**
	 * 创建索引
	 * @param key
	 * @param num
	 */
	public  static void  index(String key,int num){

		if(indexMap.containsKey(key)){
			BitVector bv = indexMap.get(key);
			bv.set(num);
			indexMap.put(key, bv);//更新
		}else{
			BitVector bv = new BitVector(10);//假设就10篇文章
			//初始化都为False
			for(int i = 0;i<10;i++){
				bv.clear(i);
			}
			bv.set(num);
			indexMap.put(key, bv);
		}
	}

	/***
	 * 在索引上进行搜索
	 * @param keyList 关键字列表
	 * @return 文章编号列表
	 */
	public static List search(List keyList){
		Set keySet = indexMap.keySet();
		BitVector bv = indexMap.get(keyList.get(0));
		for(int i =1;i<keyList.size();i++){
                //按位与结果中位图向量上为1的代表词文章出现了所有关键词
			bv=bv.comp(indexMap.get(keyList.get(i)));
		}
		List result = new ArrayList();
		for(int i = 0;i<bv.size();i++){
			if(bv.get(i)){
				result.add(Integer.valueOf(i));
			}
		}
		return result;
	}

}


索引中用到了一个位图向量,位图向量在解决存储空间压缩,整数排序等方面很有优势。
package store;

import java.io.IOException;

/**
 * 一个位图向量
 * @author zhangdp
 *
 */
public final class BitVector {

  private byte[] bits;
  private int size;
  private int count = -1;


  public BitVector(int n) {
    size = n;
    bits = new byte[(size >> 3) + 1];
  }


  /**
   * 将第bit位的值设置为1
   * @param bit
   */
  public final void set(int bit) {
    bits[bit >> 3] |= 1 << (bit & 7);
    count = -1;
  }


  /**
   * 将第bit位的值设置为0
   * @param bit
   */
  public final void clear(int bit) {
    bits[bit >> 3] &= ~(1 << (bit & 7));
    count = -1;
  }


  /**
   * 如果第i位的值为1返回True,否则返回False
   * @param bit
   * @return
   */
  public final boolean get(int bit) {
    return (bits[bit >> 3] & (1 << (bit & 7))) != 0;
  }

  public final int size() {
    return size;
  }

  /**
   * 按位&操作,两个关键词后的位图向量按位与操作,值为1位的话代表该编号
   * 文章同时出现这两个关键字,跟多关键字原理相同
   * @param bv
   * @return
   */
  public final BitVector comp(BitVector bv){
	  for(int i=0;i<bv.bits.length;i++){
		  bits[i]=(byte) (bits[i]&bv.bits[i]);
	  }
	  return this;
  }


}



创建完了索引系统了,应该再创建一个查询系统,不然就没有用了啊。

package search;

import java.util.List;

import store.IndexMap;
import store.StoreMap;

/**
 * 一个最简单的搜索类
 * @author zhangdp
 *
 */
public class SimpleSearch {

	/**
	 * 搜索并打印出来结果
	 * @param list 关键字列表
	 * @return 文件编号列表
	 */
	public void search(List list){
		//搜索到的文章编号
		List result = IndexMap.search(list);
		//显示搜索结果
		for(int i = 0;i<result.size();i++){
			Integer it = (Integer) result.get(i);
			System.out.println(StoreMap.get(it));
		}
	}
}



最后测试一下吧,是能做到多关键字搜索吧。
package test;

import java.util.List;
import java.util.ArrayList;

import search.SimpleSearch;
import store.StoreMap;
import index.SimpleIndex;

public class TestMain {

	public static void main(String args[]){
		String s1 = "Google is a engine";
		String s2 = "baidu is a engine";
		String s3 = "soso is a engine and javaeye is not";
		
		StoreMap.put(1, s1);
		StoreMap.put(2, s2);
		StoreMap.put(3, s3);
		SimpleIndex si = new SimpleIndex();
		
		si.index(1, s1);
		si.index(2, s2);
		si.index(3, s3);
		SimpleSearch ss = new SimpleSearch();
		List list = new ArrayList();
		list.add("is");//关键字列表
		list.add("javaeye");
		ss.search(list);
	}
}

2
1
分享到:
评论
1 楼 jayje 2010-01-05  
想法不错。不过还需要多完善!

相关推荐

    java实现根据关键字查找所在文件夹的文件

    在Java编程语言中,实现根据关键字查找文件夹内包含该关键字的文件是一项常见的任务,尤其在数据处理、日志分析或者文件管理系统中。这个功能可以帮助用户快速定位到含有特定信息的文件,提高工作效率。以下是一个...

    Linux中Java变量与java关键字。MyEclipse快捷键大全。Java方法

    而"Linux中Java变量.txt"和"java关键字.txt"则分别详细阐述了这两个主题,提供了更深入的学习材料。 总的来说,熟练掌握Linux环境下Java编程的变量和关键字,了解并运用MyEclipse的快捷键,以及理解和运用Java方法...

    java中50个关键字的作用

    java中50个关键字的作用 Abstract break continue final protected ==

    java统计正文中关键字个数

    实现一个类KeywordIdentifier,读入一个java程序源文件,输出各个关键字的个数(注意,注释中出现的关键字不计入关键字个数)

    java统计关键字个数

    通过args传参,读取文件,统计java代码中的关键字个数

    Java中的static关键字

    Java 中的 static 关键字是用于声明类的成员变量和成员方法的,它可以使得变量和方法属于类本身,而不属于某个对象。静态变量也称为类变量,静态方法也称为类方法。静态变量和静态方法可以直接通过类名调用,不需要...

    java保留字、关键字

    在Java编程语言中,保留字(Reserved Words)和关键字(Keywords)是两个非常重要的概念,它们构成了Java语法的基础。保留字是Java语言已经预定义并赋予特定含义的词汇,而关键字则是Java语法结构中不可或缺的部分。...

    JAVA基本语法及关键字.chm

    JAVA的基本语法及48个关键字! chm文档! 找了好久都找不到,只好自己做一个了! 分享一下...

    Java编程 标识符和关键字

    Java 语言使用的关键字包括 boolean、byte、char、short、int、long、float、double 等基本数据类型,package、import 等包声明和包引入,class、interface、extends、implements 等类或接口的声明,if、else、...

    java 变量、关键字

    这些关键字定义了Java语言的基本语法结构,例如`class`用于定义类,`public`用于声明公开访问权限。 **3. 关键字的使用** - **注意事项**:关键字不可用作标识符,如类名、变量名等。 - **保留关键字**:`goto`是...

    JAVA中的保留关键字

    Java中有53个关键字,包括但不限于: - `abstract`:用于声明抽象类和抽象方法。 - `boolean`:表示布尔类型,只有两个可能的值:true 和 false。 - `break`:用于中断循环或switch语句。 - `byte`:一种基本数据...

    Java关键字详细解

    这篇文档《Java关键字详细解》将深入探讨Java中的关键字及其用途。 首先,我们来看看Java中的主要关键字。`public`、`private`、`protected`是访问修饰符,用于控制类、方法和变量的访问权限。`public`可以被任何...

    java-标识符-关键字-数据类型课件.pptx

    Java 标识符、关键字、数据类型 Java 中的标识符是指在 Java 中命名类、接口、变量、常量、方法、属性等的名称。标识符的命名原则是: 1. 由 Unicode 字母(包括汉字)、下划线(_)、美元符($)开始,数字不能打...

    java中带super关键字的程序内存分析

    这个关键字在处理继承关系时特别有用,帮助我们更好地理解和操作对象的层次结构。在这个主题中,我们将深入探讨`super`关键字在内存分析中的作用,以及如何在子类中通过`super`来访问和调用父类的方法。 首先,让...

    Java 关键字定位位置

    在这个场景中,我们需要实现一个功能,即通过输入特定的关键字来搜索PDF文档,并确定这些关键字在文件中的具体位置。 首先,我们要了解Java中处理PDF的库。Apache PDFBox是一个常用的选择,它是一个开源项目,提供...

    java关键字和java命名规范.pdf

    Java关键字是Java语言内置的、具有特殊用途的保留字,而命名规范则是关于如何给类、方法、变量等命名的约定。 ### Java关键字 Java关键字(也称为保留字)是指在Java语言中具有特殊含义的词,它们不能用作变量名、...

    java中的关键字大全

    抽象类是不能被实例化的类,通常包含一个或多个抽象方法。抽象方法是没有实现体的方法,需要在子类中重写。 ```java public abstract class Animal { public abstract void makeSound(); } ``` ##### continue `...

    java中“53”个关键字(含2个保留字)

    在Java中,一共有53个关键字,包括两个保留字。下面将详细阐述这些关键字的功能和用途。 1. `abstract` - 用于声明抽象类或抽象方法,表示类不提供具体实现。 2. `assert` - 用于断言某个条件为真,通常用于测试和...

    java里的关键字

    一个类可以实现多个接口。 ```java interface Printable { void print(); } interface Showable { void show(); } class Book implements Printable, Showable { public void print() { System.out.println(...

    java关键字

    ### Java关键字详解 ...每个关键字都有其特定的用途和规则。通过深入理解这些关键字的功能,开发者能够更高效地编写清晰、简洁且易于维护的代码。希望本文的介绍能帮助读者更好地理解和运用Java的关键字。

Global site tag (gtag.js) - Google Analytics