Java 교사는 한 번 바이두에 대한 인터뷰 질문을했는데, 이는 "10,000 개의 무질서한 기록이 있으며, 원하는 기록을 빠르게 찾는 방법"을 의미합니다. 이것은 간단한 검색 엔진과 동일합니다. 최근에, 나는 올해 내가 정리 한 작업에서 이미 이것을 깨달았습니다. 오늘 나는 당신과 더 추상적으로 공유 할 것입니다.
먼저 특정 구현 코드를 작성하고 코드 후 특정 구현 아이디어 및 논리를 작성하십시오.
검색 중에 분류에 사용되는 콩
/ ** *@description : */ package cn.lulei.search.engine.model; 공개 클래스 SortBean {개인 문자열 ID; 개인 int 시간; 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; }} 검색 데이터 구조 및 간단한 검색 알고리즘을 구성했습니다
/ ** *@description : */ package cn.lulei.search.engine; java.util.arraylist 가져 오기; java.util.collections import; import java.util.comparator; java.util.hashmap import; java.util.hashset 가져 오기; Java.util.list 가져 오기; cn.lulei.search.engine.model.sortbean import; 공개 클래스 SARACHBASE {// 세부 사항 저장 검색 개체의 자세한 정보, 여기서 키는 객체 개인 해시 맵 <문자열, 객체> 세부 사항을 구별하는 고유 식별자입니다. // 검색에 참여하는 키워드의 경우 여기에 사용 된 스파 스 스토리지도 HashMap을 사용하여 저장할 수도 있습니다. 정의 형식은 다음과 같습니다. // 해시 맵 매체의 키 값은 스파 스 배열의 첨자와 동일하며 값은이 위치에서 드문 배열의 값과 동일합니다. @SuppressWarnings ( "선택 취소") Private Hashset <string> [] Keysearch = New Hashset [MaxLength]; / ***@description : 싱글 톤 모드 구현, 초기화에 대한 초기화 홀더를 사용하여*@버전 : 1.1.0*/ private static class lazyloadserachbase {private static final serachbase sarachbase = new sarachbase (); } / *** 싱글 톤 모드는 여기에서 개인 기능으로 설정됩니다* / private sarachbase () {} / *** @return* @description : get singleton* / public static serachbase getSerachbase () {return lazyloadserachbase.serachbase; } / ** * @param id * @return * @description : id * / public object getObject (string id) {return details.get (id); } / ** * @param ids * @return * @description : IDS를 기반으로 세부 정보를 얻고, ID를 " * / public list <botorbjects (string ids) {if (ids == null ||" ".Equals (ids)) {return null; } list <bood> objs = new ArrayList <Object> (); 문자열 [] idarray = ids.split ( ","); for (string id : idarray) {objs.add (getObject (id)); } return objs; } / ** * @param key * @return * @description : 검색어에 따라 해당 ID를 찾아 사용합니다. } // 찾기 // 검색어의 각 문자가 ID의 ID에 표시되는지 여부를 저장합니다. idtimes = new Hashmap <String, integer> idtimes = new Hashmap <String, integer> (); // IDS는 검색어에 문자의 ID를 저장합니다. Hashset <string> ids = new Hashset <문자열> (); // (int i = 0; i <key.length (); i ++) {int at = key.charat (i); // 검색어에 해당 문자가 없습니다. 그런 다음 다음 문자를 일치시킵니다. } for (object obj : keysearch [at] .toArray ()) {String id = (string) obj; int times = 1; if (ids.contains (id)) {times += idtimes.get (id); idtimes.put (id, times); } else {ids.add (id); idtimes.put (id, times); }}} // 배열 목록으로 정렬 <Sortbean> SortBeans = new ArrayList <SortBean> (); for (string id : ids) {Sortbean Sortbean = new Sortbean (); Sortbeans.add (Sortbean); SortBean.setId (id); SortBean.setTimes (idtimes.get (id)); } collections.SORT (SortBeans, New Comparator <SortBean> () {public int compare (SortBean O1, SortBean O2) {return o2.getTimes () - o1.getTimes ();}}); // return Return String StringBuffer sb = new StringBuffer (); for (sortbean sortbean : sortbeans) {sb.append (sortbean.getid ()); sb.append ( ","); } // resource idtimes.clear ()를 릴리스합니다. idtimes = null; ids.clear (); ids = null; SortBeans.clear (); SortBeans = null; // return return sb.toString (); } /** * @param id * @param searchkey * @param obj * @description : 검색 기록 추가 * /public void add (문자열 id, 문자열 searchkey, object obj) {// 매개 변수는 부분적으로 비어 있고 (id == null || searchkey == null || obj == null) {return; } // 객체 세부 사항을 저장합니다. put (id, obj); // 검색 용어 저장 AddSearchKey (id, searchKey); }/** * @param id * @param searchkey * @description : 검색 도메인에 검색어 추가 */private void addsearchkey (string id, string searchkey) {// 별도의 매개 변수는 비어 있고로드되지 않은 // 이것은 개인 방법이지만 다음 판단은 (id = null || searchKey == null) {null) {null). } // 다음은 문자 분사입니다. 여기에서는 (int i = 0; i <searchkey.length (); i ++) {// at의 값은 배열의 첨자와 동일하며 ID로 구성된 해시 세트는 배열 int at = searchkey.charat (i)의 값과 동일합니다. if (keysearch [at] == null) {hashset <string> value = new Hashset <string> (); Keysearch [at] = value; } keysearch [at] .add (id); }}} 테스트 사례 :
/ ** *@description : */ package cn.lulei.search.engine.test; Java.util.list 가져 오기; cn.lulei.search.engine.serachbase import; 공개 클래스 테스트 {public static void main (string [] args) {// todo 자동 생성 메소드 스터브 sarachbase sarachbase = serachbase.getSerachbase (); sarachbase.add ( "1", "hello!", "hello!"); sarachbase.add ( "2", "안녕하세요! 나는 Zhang San입니다.", "안녕하세요! 나는 Zhang San입니다."); sarachbase.add ( "3", "오늘 날씨가 꽤 좋습니다."); sarachbase.add ( "4", "당신은 누구입니까?", "당신은 누구입니까?"); sarachbase.add ( "5", "고급 수학의 주제는 어렵다", "높은 수학은 실제로 어렵다"); sarachbase.add ( "6", "test", "위는 단지 테스트입니다"); 문자열 ids = sarachbase.getIds ( "당신의 높은 수학"); System.out.println (IDS); List <Object> objs = sarachbase.getObjects (ids); if (objs! = null) {for (object obj : objs) {system.out.println ((String) obj); }}}} 테스트 출력 결과는 다음과 같습니다.
5, 3, 2, 1, 4, 더 높은 숫자는 실제로 어렵다. 오늘 날씨는 꽤 좋습니다. 안녕하세요! 나는 Zhang San입니다. 안녕하세요! 누구세요?
이러한 간단한 검색 엔진은 완성 된 것으로 간주됩니다.
질문 1 : 여기에 분사라는 단어는 캐릭터 분사를 사용합니다.이 문자는 중국어를 다루는 데 매우 능숙하지만 영어를 다루는 데 매우 약합니다.
개선 방법 : ikanalyzer, StandardAnalyzer 등과 같은 현재 성숙한 단어 세분화 방법을 사용하십시오. 이러한 방식으로 Keysearch의 데이터 구조는 수정되어야하며, 이는 개인 해시 <String, String> [] Keysearch = new Hashmap [maxlength]로 수정할 수 있습니다. 여기서 키는 부품의 단어 요소를 저장하고 값은 고유 식별자 ID를 저장합니다.
질문 2 : 이 기사에서 구현 된 검색 엔진은 Lucene과 같은 단어 요소의 가중치를 설정하지 않고 단순히 단어 요소가 객체에 나타나는지 여부를 결정합니다.
개선 방법 : 아직 없음. 웨이트 처리를 추가하면 데이터 구조가 더욱 복잡해 지므로 당분간 처리되지 않았으며 향후 기사에서 웨이트 처리가 구현 될 것입니다.
검색 엔진의 구현 아이디어를 간단히 소개하겠습니다.
Serachbase 클래스에서 세부 사항과 Keysearch의 두 가지 속성을 설정하십시오. 세부 사항은 객체의 자세한 정보를 저장하는 데 사용되며 Keysearch는 검색 도메인을 색인하는 데 사용됩니다. 세부 사항 데이터 형식은 Hashmap이며 Keysearch의 데이터 형식은 희소 배열입니다 (Hashmap 일 수도 있고 HashMap 중간 키 값은 희소 배열의 첨자와 동일하며 값은이 위치에서 드문 배열의 값과 동일합니다).
세부 사항에 대해 너무 많은 소개를하지 않을 것입니다.
Keysearch에서 배열 위트의 계산 방법 (예 : Hashmap은 핵심)은 단어 요소의 첫 번째 문자 int 값을 얻는 것입니다 (이 기사의 단어가 문자 분사를 사용하기 때문에 문자는 단어 요소이기 때문입니다). int 값은 배열의 첨자이며 해당 배열 값은 객체의 고유 식별자입니다. 이런 식으로 Keysearch의 데이터 구조는 다음과 같습니다.
따라서 새 레코드를 추가하려면 추가 메소드 만 호출하면됩니다.
검색을위한 구현 로직은 위의 키 검색과 유사합니다. ID 검색의 경우 Hashmap의 GET 메소드를 사용하십시오. 검색어 검색을 위해 전체 프로세스는 먼저 워드 세분화, 쿼리 두 번째 및 마지막으로 정렬 된 것을 사용합니다. 물론, 여기서 분사라는 단어는 생성하는 데 사용되는 단어와 일치해야합니다 (즉, 캐릭터 분사는 생성 할 때 사용되며 캐릭터 분사도 검색 할 때 사용됩니다).
getIDS 메소드에서 Hashmap <String, Integer> idtimes = new Hashmap <String, integer> (); idtimes 변수는 검색어에서 Keysearch에 나타나는 단어 요소 수를 저장하는 데 사용됩니다. 핵심 값은 고유 식별자 ID이고 값은 나타나는 단어 요소의 수입니다. Hashset <string> ids = new Hashset <문자열> (); IDS 변수는 단어 발생의 ID를 저장하는 데 사용됩니다. 이러한 방식으로 검색의 복잡성은 검색어의 단어 요소 N 수입니다. 단어 요소가 포함 된 ID를 얻고 SortBean 배열을 구성하고 정렬하십시오. 분류 규칙은 단어 요소 수의 순서를 내리는 것입니다. 마지막으로 IDS 문자열이 반환되고 각 ID는 ","로 나뉩니다. 자세한 정보를 얻으려면 getObjects 메소드를 사용하십시오.
위의 것은 단순한 검색 엔진 일 뿐이며 너무 많은 계산 방법을 설계하지 않았습니다. 모든 사람의 학습에 영감을주기를 바랍니다.