Lembro que o professor de Java disse uma vez uma pergunta de entrevista no Baidu, que significa aproximadamente "existem 10.000 registros desordenados, como encontrar rapidamente os registros que você deseja deles". Isso é equivalente a um mecanismo de pesquisa simples. Recentemente, já percebi isso no trabalho que resolvi este ano. Hoje vou compartilhar com você abstrair ainda mais.
Primeiro, escreva código de implementação específico e escreva idéias e lógica de implementação específicas após o código.
Feijão usado para classificar durante a pesquisa
/ ** *@Descrição: */ package cn.lulei.search.engine.model; classe pública Sortbean {private string ID; privado int times; public string getId () {return id; } public void setId (string id) {this.id = id; } public int getTimes () {Return times; } public void Settimes (int times) {this.Times = times; }} Estrutura de dados de pesquisa construída e algoritmo de pesquisa simples
/ ** *@Descrição: */ package cn.lulei.search.engine; importar java.util.arraylist; importar java.util.Collections; importar java.util.comparator; importar java.util.hashmap; importar java.util.hashset; importar java.util.list; importar cn.lulei.search.engine.model.sortbean; classe pública Serachbase {// Detalhes armazenam informações detalhadas dos objetos de pesquisa, onde a chave é o identificador exclusivo para distinguir o objeto privado hashmap <string, object> detalhes = new hashmap <string, object> (); // Para palavras -chave que participam da pesquisa, o armazenamento de matriz esparsa usado aqui também pode ser armazenado usando o hashmap. O formato de definição é o seguinte // private estático hashmap <inteiro, hashset <string>> KeySearch = new Hashmap <Inteiro, HashSet <String>> (); // O valor da chave do meio de hashmap é equivalente ao subscrito na matriz esparsa, e o valor é equivalente ao valor da matriz esparsa nesta posição, private final estático int maxLength = caractere.max_value; @Suppresswarnings ("desmarcado") privado hashset <string> [] KeySearch = new HashSet [maxLength]; / ***@Descrição: Implemente o modo singleton, usando o titular da demanda de inicialização para carregar*@versão: 1.1.0*/ classe estática privada LazyLoadSerachbase {private estático final serachbase serachbase = new serachbase (); } / *** O modo Singleton está definido como função privada aqui* / private Serachbase () {} / *** @return* @Description: Get Singleton* / public static serachbase getSerachbase () {return lazyloadserachbase.serachbase; } / ** * @param id * @return * @description: obtenha detalhes com base no id * / public objeto getObject (string id) {return detalhets.get (id); } / ** * @param ids * @return * @Description: Obtenha detalhes com base nos IDs, separe os IDs com "," * / list public <ject> getObjects (string ids) {if (ids == null || "" .equals (ids)) {return null; } List <ject> objs = new ArrayList <ject> (); String [] idArray = ids.split (","); for (string id: idarray) {objs.add (getObject (id)); } retornar objs; } / ** * @Param Key * @return * @Description: Encontre o ID correspondente de acordo com os termos de pesquisa e use "," para dividir entre IDs * / public String getIds (String key) {if (key == null || "" .equals (key)) {return null; } // encontre // IDTimes armazena se cada caractere no termo de pesquisa aparece no ID no ID. idtimes = new hashmap <string, número inteiro> idtimes = new hashmap <string, número inteiro> (); // IDS armazena o ID dos caracteres no termo de pesquisa. HashSet <String> ids = new HashSet <String> (); // encontrando para (int i = 0; i <key.length (); i ++) {int at = key.charat (i); // Não há caráter correspondente no termo de pesquisa. Em seguida, corresponda ao próximo caractere se (KeySearch [at] == null) {continua; } para (objeto obj: keysearch [at] .toarray ()) {string id = (string) obj; int times = 1; if (ids.contains (id)) {times += idtimes.get (id); idtimes.put (id, horários); } else {ids.add (id); idtimes.put (id, horários); }}} // Classifique com a lista de matrizes <StemBean> SortBeans = new ArrayList <StemBean> (); para (string id: ids) {sortbean sortBean = new SortBean (); sortBeans.add (Sortbean); sortBean.setId (id); sortBean.setTimes (idtimes.get (id)); } Coleções.sort (Sortbeans, novo comparador <StemBean> () {public int compare (SortBean O1, Sortbean O2) {return o2.getTimes () - o1.getTimes ();}}}); // Construct Return String StringBuffer sb = new StringBuffer (); para (SortBean SortBean: Sortbeans) {sb.append (sorveBean.getId ()); sb.append (","); } // Libere o recurso idtimes.clear (); idtimes = null; ids.clear (); ids = nulo; sorBeans.clear (); sortbeans = nulo; // return return sb.toString (); } /** * @param id * @param pesquisa } // salvar detalhes do objeto.put (id, obj); // Salvar termo de pesquisa addSearchKey (id, pesquisa); }/** * @param ID * @param SearchKey * @Description: Adicione os termos de pesquisa ao domínio da pesquisa */private void AddSearchKey (string ID, String searchKey) {// parâmetros separados estão vazios e não carregados // Este é um método privado, e o seguinte julgamento pode ser feito, mas para as especificações de designa (id; } // O seguinte é o particípio do personagem. Aqui você também pode usar outros participantes da palavra madura para (int i = 0; i <searchKey.length (); i ++) {// O valor de AT é equivalente ao subscrito da matriz, e o hashset composto por ID é equivalente ao valor da matriz int em = SearchKey.Charat (i); if (keysearch [at] == null) {hashSet <String> value = new HashSet <String> (); KeySearch [at] = value; } KeySearch [at] .add (id); }}} Casos de teste:
/ ** *@Descrição: */ pacote cn.lulei.search.engine.test; importar java.util.list; importar cn.lulei.search.engine.serachbase; public class Test {public static void main (string [] args) {// TODO Método Gerado Auto-Gerado Stub Serachbase Serachbase = Serachbase.getSerachBase (); Serachbase.add ("1", "Hello!", "Hello!"); Serachbase.add ("2", "Olá! Eu sou Zhang San.", "Olá! Eu sou Zhang San."); Serachbase.add ("3", "O tempo está muito bom hoje."); Serachbase.add ("4", "Quem é você?", "Quem é você?"); Serachbase.add ("5", "O assunto da matemática avançada é difícil", "a alta matemática é realmente difícil"); Serachbase.add ("6", "teste", "o acima é apenas um teste"); String IDS = SERACHBASE.GETIDS ("Sua alta matemática"); System.out.println (IDS); List <ject> objs = serachbase.getObjects (IDS); if (objs! = null) {for (objeto obj: objs) {System.out.println ((string) obj); }}}} Os resultados da saída de teste são os seguintes:
5, 3, 2, 1, 4, números mais altos são realmente difíceis. O tempo hoje está muito bom. Olá! Eu sou Zhang San. Olá! Quem é você?
Um mecanismo de pesquisa tão simples é considerado concluído.
Pergunta 1: A palavra particípio aqui usa o particípio do personagem, que é muito bom para lidar com chinês, mas é muito fraco no lidar com o inglês.
Método de melhoria: use o método atual de segmentação de palavras maduras, como ikanalyzer, standardanalyzer, etc. Dessa forma, a estrutura de dados da pesquisa KeySearch precisa ser modificada, que pode ser modificada no hashmap privado <string, string> [] keysearch = new Hashmap [maxlengthngth]; onde a chave armazena o elemento palavra da peça e o valor armazena o identificador exclusivo ID.
Pergunta 2: O mecanismo de pesquisa implementado neste artigo não define pesos para elementos de palavras como Lucene, mas simplesmente determina se os elementos de palavras aparecem no objeto.
Método de melhoria: nenhum ainda. A adição de processamento de peso torna a estrutura de dados mais complexa, por isso não foi processada por enquanto, e o processamento de peso será implementado em artigos futuros.
Vamos apresentar brevemente as idéias de implementação dos mecanismos de pesquisa .
Defina as duas propriedades de detalhes e KeySearch na classe Serachbase. Os detalhes são usados para armazenar as informações detalhadas do objeto, e o KeySearch é usado para indexar o domínio da pesquisa. O formato de dados de detalhes é hashmap e o formato de dados da KeySearch é uma matriz esparsa (também pode ser hashmap, o valor da chave média hashmap é equivalente ao subscrito na matriz esparsa e o valor é equivalente ao valor da matriz escassa nesta posição).
Não vou dar muita introdução aos detalhes.
O método de cálculo dos subscritos de matriz no KeySearch (como o hashmap é fundamental) é obter o primeiro valor do elemento da palavra (porque o particípio da palavra neste artigo usa o particípio do personagem, então um caractere é um elemento da palavra). O valor int é o subscrito da matriz e o valor da matriz correspondente é o identificador exclusivo do objeto. Dessa forma, a estrutura de dados da KeySearch é a seguinte
Portanto, quando você deseja adicionar um novo registro, você só precisa ligar para o método Add.
A lógica de implementação da pesquisa é semelhante à pesquisa de chave acima. Para pesquisa de identificação, basta usar o método GET do hashmap. Para uma pesquisa por termos de pesquisa, o processo geral também usa a segmentação do Word primeiro, a consulta em segundo e classificada por último. Obviamente, a palavra particípio aqui deve ser consistente com a palavra particípio usado para criar (ou seja, o particípio do personagem é usado ao criar e o particípio do personagem também é usado ao pesquisar).
No método getIds, o hashmap <string, integer> idtimes = new hashmap <string, inteiro> (); a variável idtimes é usada para armazenar quantos elementos do Word no termo de pesquisa aparecem no KeySearch. O valor da chave é o ID do identificador exclusivo e o valor é o número de elementos do Word que aparecem. HashSet <String> ids = new HashSet <String> (); A variável IDS é usada para armazenar os IDs da ocorrência da palavra. A complexidade da pesquisa dessa maneira é o número de elementos de palavras n do termo de pesquisa. Obtenha os IDs contendo elementos de palavras, construa a matriz Sortbean e classifique -a. A regra de classificação é descer a ordem do número de elementos de palavras. Finalmente, a string IDS é retornada e cada ID é dividido por "". Se você deseja obter informações detalhadas, use o método getObjects.
O acima é apenas um mecanismo de pesquisa simples e não projetou muitos métodos de cálculo. Espero que inspire todos o aprendizado de todos.