Recuerdo que el maestro de Java dijo una vez una pregunta de entrevista sobre Baidu, que significa aproximadamente "hay 10,000 registros desordenados, cómo encontrar rápidamente los registros que desea de ellos". Esto es equivalente a un simple motor de búsqueda. Recientemente, ya me he dado cuenta de esto en el trabajo que he resuelto este año. Hoy compartiré con ustedes más abstracto.
Primero escriba un código de implementación específico y escriba ideas de implementación específicas y lógica después del código.
Frijoles utilizados para clasificar durante la búsqueda
/ ** *@Descripción: */ paquete cn.lulei.search.engine.model; clase pública SortBean {ID de cadena privada; Times de intento privado; public String getId () {return id; } public void setid (ID de cadena) {this.id = id; } public int getTimes () {return times; } public void settimes (intimio) {this.times = Times; }} Estructura de datos de búsqueda construida y algoritmo de búsqueda simple
/ ** *@Descripción: */ paquete cn.lulei.search.engine; import java.util.arrayList; import java.util.collections; importar java.util.comparator; import java.util.hashmap; import java.util.hashset; import java.util.list; import cn.lulei.search.engine.model.sortbean; clase pública Serachbase {// Detalles almacena información detallada de los objetos de búsqueda, donde la clave es el identificador único para distinguir el objeto hashmap privado <string, objeto> detalles = new Hashmap <String, object> (); // Para las palabras clave que participan en la búsqueda, el almacenamiento de matriz disperso utilizado aquí también se puede almacenar usando HashMap. El formato de definición es el siguiente // hahmap estático privado <Integer, Hashset <String>> KeySearch = new HashMap <Integer, Hashset <String> (); // El valor clave del medio hashmap es equivalente al subíndice en la matriz dispersa, y el valor es equivalente al valor de la matriz dispersa en esta posición, la estática final privada int maxLength = caracteres.max_value; @SupessWarnings ("sin verificar") hashset privado <string> [] keySearch = new Hashset [maxLength]; / ***@Descripción: Implementar el modo Singleton, utilizando el soporte de inicialización de la demanda para cargar*@versión: 1.1.0*/ clase privada estática LazyLoadSerachBase {private static final Serachbase Serachbase = new Serachbase (); } / *** El modo Singleton está configurado en función privada aquí* / private serachbase () {} / *** @return* @Description: get singleton* / public static serachbase getSerachBase () {return LazyLoadSerachBase.serachBase; } / ** * @param id * @return * @Description: Obtenga detalles basados en ID * / public Object getObject (ID de cadena) {return Details.get (id); } / ** * @param ids * @return * @Description: Obtenga detalles basados en IDS, separe los ID con "," * / public List <Sect> getObjects (String IDS) {if (IDS == NULL || "" .Equals (IDS)) {return null; } List <S Object> objs = new ArrayList <ject> (); Cadena [] idarray = id.split (","); for (ID de cadena: IDArray) {objs.Add (getObject (id)); } return objs; } / ** * @param clave * @return * @Description: busque la identificación correspondiente de acuerdo con los términos de búsqueda y use "," para dividir entre IDS * / public String getIds (clave de cadena) {if (key == null || "" .equals (key)) {return null; } // encontrar // IDTimes almacena si cada personaje en el término de búsqueda aparece en la ID en la ID. IDTimes = new HashMap <String, Integer> IdTimes = new HashMap <String, Integer> (); // IDS almacena la identificación de los caracteres en el término de búsqueda. Hashset <String> IDS = new Hashset <String> (); // encontrar para (int i = 0; i <key.length (); i ++) {int at = key.charat (i); // No hay carácter correspondiente en el término de búsqueda. Luego coincida con el siguiente carácter if (keySearch [at] == null) {continuar; } for (object obj: keySearch [at] .toarray ()) {string id = (string) obj; intimes = 1; if (id.contains (id)) {Times += idtimes.get (id); IDTimes.put (id, tiempos); } else {id.add (id); IDTimes.put (id, tiempos); }}} // Ordenar con la lista de matriz <AdtBean> sortBeans = new ArrayList <SortBean> (); for (cadena id: ids) {sortBean sortBean = new SortBean (); sortBeans.add (sortBean); sortBean.SetId (id); sortBean.settimes (idtimes.get (id)); } Colección.sort (sortBeans, nuevo comparador <AdBean> () {public int Compare (sortBean O1, sortBean O2) {return o2.gettimes () - o1.gettimes ();}}); // construye return string stringBuffer sb = new StringBuffer (); para (sortBean sortBean: sortBeans) {sb.append (sortBean.getID ()); sb.append (","); } // libera el recurso idtimes.clear (); IdTimes = nulo; IDS.CLEAR (); IDS = nulo; sortBeans.clear (); sortBeans = null; // return return sb.ToString (); } /** * @param id * @param searchKey * @param obj * @Description: Agregar historial de búsqueda * /public void add (string id, string searchkey, object obj) {// Los parámetros están parcialmente vacíos y no cargan si (id == null || SearchKey == null || obj == null) {return; } // Guardar detalles del objeto.put (id, obj); // Guardar el término de búsqueda addSearchKey (id, SearchKey); }/** * @param id * @param searchkey * @Description: agregue los términos de búsqueda al dominio de búsqueda */private void addsearchKey (id id de cadena, string searchkey) {// Los parámetros separados están vacíos y no cargados // Este es un método privado, y se puede hacer el siguiente juicio, pero para el sake de las especificaciones de diseño, si (id == null || SearchKey == null); } // El siguiente es el participio de los personajes. Aquí también puede usar otros participantes de palabras maduras para (int i = 0; i <searchkey.length (); i ++) {// El valor de AT es equivalente al subíndice de la matriz, y el heta compuesto por ID es equivalente al valor de la matriz int at = searchKey.charat (i); if (keySearch [at] == null) {Hashset <String> value = new Hashset <String> (); KeySearch [at] = valor; } KeySearch [AT] .Add (id); }}} Casos de prueba:
/ ** *@Descripción: */ paquete cn.lulei.search.engine.test; import java.util.list; import cn.lulei.search.engine.serachbase; Prueba de clase pública {public static void main (string [] args) {// TODO Método auto generado stub Serachbase Serachbase = Serachbase.getSerachBase (); Serachbase.add ("1", "¡Hola!", "¡Hola!"); Serachbase.add ("2", "¡Hola! Soy Zhang San", "¡Hola! Soy Zhang San"); Serachbase.add ("3", "El clima es bastante bueno hoy"); Serachbase.add ("4", "¿Quién eres?", "¿Quién eres?"); Serachbase.add ("5", "El tema de las matemáticas avanzadas es difícil", "Las matemáticas altas son realmente difíciles"); Serachbase.add ("6", "prueba", "lo anterior es solo prueba"); IDS de cadena = Serachbase.getIds ("Sus altas matemáticas"); System.out.println (IDS); Lista <S Object> objs = Serachbase.getObjects (IDS); if (objs! = null) {for (object obj: objs) {system.out.println ((string) obj); }}}} Los resultados de la salida de prueba son los siguientes:
5, 3, 2, 1, 4, los números más altos son realmente difíciles. El clima de hoy es bastante bueno. ¡Hola! Soy Zhang San. ¡Hola! ¿Quién eres?
Se considera que un motor de búsqueda tan simple se completa.
Pregunta 1: La palabra participio aquí usa el participio de personajes, que es bastante bueno para manejar el chino, pero es muy débil en el manejo del inglés.
Método de mejora: use el método actual de segmentación de palabras maduras, como iKanalyzer, StandardAnalyzer, etc. De esta manera, la estructura de datos de KeySearch debe modificarse, que puede modificarse a hashmap privado <String, String> [] KeySearch = New HashMap [MaxLength]; donde la clave almacena el elemento de la palabra de la pieza, y el valor almacena la identificación de identificador única.
Pregunta 2: El motor de búsqueda implementado en este artículo no establece pesos para elementos de palabras como Lucene, sino que simplemente determina si los elementos de palabras aparecen en el objeto.
Método de mejora: ninguno todavía. Agregar procesamiento de peso hace que la estructura de datos sea más compleja, por lo que no se ha procesado por el momento, y el procesamiento de peso se implementará en futuros artículos.
Presentemos brevemente las ideas de implementación de los motores de búsqueda .
Establezca las dos propiedades de los detalles y la búsqueda de teclas en la clase Serachbase. Los detalles se utilizan para almacenar la información detallada del objeto, y KeySearch se utiliza para indexar el dominio de búsqueda. El formato de datos de detalles es HASHMAP, y el formato de datos de KeySearch es una matriz dispersa (también puede ser HASHMAP, el valor de la clave de Medio HashMAP es equivalente al subíndice en la matriz dispersa, y el valor es equivalente al valor de la matriz dispersa en esta posición).
No daré demasiada introducción a los detalles.
El método de cálculo de los subíndices de matriz en KeySearch (como hashmap es clave) es obtener el primer carácter intel valor del elemento de palabra (porque el participio de la palabra en este artículo usa el participio de los caracteres, por lo que un carácter es un elemento de palabra). El valor int es el subíndice de la matriz, y el valor de matriz correspondiente es el identificador único del objeto. De esta manera, la estructura de datos de KeySearch es la siguiente
Por lo tanto, cuando desea agregar un nuevo registro, solo necesita llamar al método Agregar.
La lógica de implementación para la búsqueda es similar a la investigación de tecla anterior. Para la búsqueda de identificación, solo use el método GET de HashMap. Para una búsqueda de términos de búsqueda, el proceso general también utiliza la segmentación de palabras primero, consulta segunda y ordenada por último. Por supuesto, el participio de la palabra aquí debe ser consistente con la palabra participio utilizado para crear (es decir, el participio de los personajes se usa al crear y el participio de los caracteres también se usa al buscar).
En el método getIds, el hashmap <string, integer> idtimes = new HashMap <String, Integer> (); IDTimes Variable se usa para almacenar cuántos elementos de palabras en el término de búsqueda aparecen en KeySearch. El valor clave es el ID de identificador único y el valor es el número de elementos de palabras que aparecen. Hashset <String> IDS = new Hashset <String> (); La variable IDS se utiliza para almacenar las ID de la aparición de la palabra. La complejidad de la búsqueda de esta manera es el número de elementos de palabras n del término de búsqueda. Obtenga los ID que contienen elementos de palabras, construyen la matriz de mando de Sortbean y ordenarlo. La regla de clasificación es descender el orden del número de elementos de palabras. Finalmente, se devuelve la cadena IDS, y cada ID se divide por ",". Si desea obtener información detallada, use el método GetObjects.
Lo anterior es solo un simple motor de búsqueda y no ha diseñado demasiados métodos de cálculo. Espero que inspire el aprendizaje de todos.