最近看了《数学之美系列五》-- 简单之美:布尔代数和搜索引擎的索引。
通过文章的介绍,了解了搜索引擎的原理,就动手尝试了一下。代码除了学习最基本原理外没有任何价值。所有的操作都是内存操作,与真实的商用搜索系统相差甚远。
首先创建一个索引器,这是最最简单的索引器。
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);
}
}
分享到:
相关推荐
在Java编程语言中,实现根据关键字查找文件夹内包含该关键字的文件是一项常见的任务,尤其在数据处理、日志分析或者文件管理系统中。这个功能可以帮助用户快速定位到含有特定信息的文件,提高工作效率。以下是一个...
在Java开发中,处理PDF文档是一项常见的任务,特别是在需要搜索、提取或替换PDF中的特定信息时。本篇文章将深入探讨如何使用iText库在Java中实现PDF关键字定位。iText是一个强大的PDF处理库,它提供了丰富的API来...
java的50个关键字及其含义,适合java入门学习
java volatile 关键字实战java volatile 关键字实战java volatile 关键字实战java volatile 关键字实战java volatile 关键字实战java volatile 关键字实战java volatile 关键字实战java volatile 关键字实战java ...
了解和掌握Java关键字是每一个Java开发者必备的技能。 下面是Java关键字大全的详细说明: 1. abstract abstract关键字用于定义抽象类和抽象方法。抽象类不能实例化,必须被子类继承和实现。抽象方法必须在子类中...
searchEngine 是基于 ElasticSearch 和 Java 实现的搜索引擎系统,实现关键字高亮搜索、添加文本等功能。 该项目集成了 Spring Boot、ElasticSearch、RestHighLevelClient、Vue.js、Element-ui、Log4j 和 Fastjson ...
在Java编程语言中,保留字(Reserved Words)和关键字(Keywords)是两个非常重要的概念,它们构成了Java语法的基础。保留字是Java语言已经预定义并赋予特定含义的词汇,而关键字则是Java语法结构中不可或缺的部分。...
这份“JAVA基础笔记以及关键字整理.rar”压缩包包含了全面的Java基础知识和关键字的详细讲解,对于初学者和有一定经验的开发者来说,都是一个极好的学习和复习资源。 首先,Java的基础知识涵盖了许多方面。包括但不...
Java的关键字一共51个,包括访问控制修饰符(如public、private、protected)、控制流程关键字(如if、else、for、while)、数据类型关键字(如int、char、boolean)、异常处理关键字(如try、catch、finally)等。...
在Java编程语言中,提取文章关键字是一项常见的自然语言处理任务,它涉及到文本挖掘和信息检索领域。这个任务的目的是从一篇文章中识别出最具代表性的词语或短语,这些词汇通常反映了文章的主题和核心内容。在Java中...
5. `final`: 这个关键字用于声明不可变的变量,一旦赋值就不能更改。它也可以应用于方法,表示该方法不能被子类重写,或者应用于类,表示此类不能被继承。 6. `void`: 在方法定义中,`void`表示该方法不返回任何值...
这些关键字定义了Java语言的基本语法结构,例如`class`用于定义类,`public`用于声明公开访问权限。 **3. 关键字的使用** - **注意事项**:关键字不可用作标识符,如类名、变量名等。 - **保留关键字**:`goto`是...
这篇文档《Java关键字详细解》将深入探讨Java中的关键字及其用途。 首先,我们来看看Java中的主要关键字。`public`、`private`、`protected`是访问修饰符,用于控制类、方法和变量的访问权限。`public`可以被任何...
在这个场景中,我们需要实现一个功能,即通过输入特定的关键字来搜索PDF文档,并确定这些关键字在文件中的具体位置。 首先,我们要了解Java中处理PDF的库。Apache PDFBox是一个常用的选择,它是一个开源项目,提供...
java学习-java中的abstract关键字
抽象类是不能被实例化的类,通常包含一个或多个抽象方法。抽象方法是没有实现体的方法,需要在子类中重写。 ```java public abstract class Animal { public abstract void makeSound(); } ``` ##### continue `...
在Java中,一共有53个关键字,包括两个保留字。下面将详细阐述这些关键字的功能和用途。 1. `abstract` - 用于声明抽象类或抽象方法,表示类不提供具体实现。 2. `assert` - 用于断言某个条件为真,通常用于测试和...
在Java编程语言中,`static`关键字是一个非常重要的修饰符,它有多种用途,涉及到类、对象以及变量和方法的生命周期。本视频教程详细讲解了`static`关键字在Java中的应用及其背后的原理。 首先,我们要理解`static`...
一个类可以实现多个接口。 ```java interface Printable { void print(); } interface Showable { void show(); } class Book implements Printable, Showable { public void print() { System.out.println(...
### Java关键字详解 #### 1. abstract - **定义与用途**:`abstract`关键字用于定义抽象类或抽象方法。抽象类是指无法直接实例化的类,而抽象方法是没有实现体的方法,它们都需要在子类中具体实现。 - **示例**:...