ฉันจำได้ว่าครู Java เคยกล่าวคำถามสัมภาษณ์เกี่ยวกับ Baidu ซึ่งหมายถึง "มีบันทึกที่ไม่เป็นระเบียบ 10,000 บันทึกวิธีการค้นหาบันทึกที่คุณต้องการจากพวกเขาอย่างรวดเร็ว" สิ่งนี้เทียบเท่ากับเครื่องมือค้นหาอย่างง่าย เมื่อเร็ว ๆ นี้ฉันได้ตระหนักถึงสิ่งนี้ในงานที่ฉันได้แยกออกในปีนี้ วันนี้ฉันจะแบ่งปันกับคุณนามธรรมต่อไป
ก่อนอื่นเขียนรหัสการใช้งานเฉพาะและเขียนแนวคิดการใช้งานเฉพาะและตรรกะหลังจากรหัส
ถั่วที่ใช้ในการเรียงลำดับระหว่างการค้นหา
/ ** *@คำอธิบาย: */ แพ็คเกจ cn.lulei.search.engine.model; คลาสสาธารณะ SortBean {รหัสสตริงส่วนตัว; เวลา int ส่วนตัว; สตริงสาธารณะ getId () {return id; } โมฆะสาธารณะ setId (รหัสสตริง) {this.id = id; } public int getTimes () {เวลากลับ; } void public settimes (เวลา int) {this.times = times; - โครงสร้างข้อมูลการค้นหาที่สร้างขึ้นและอัลกอริทึมการค้นหาอย่างง่าย
/ ** *@คำอธิบาย: */ แพ็คเกจ cn.lulei.search.engine; นำเข้า java.util.arraylist; นำเข้า Java.util.Collections; นำเข้า Java.util.Comparator; นำเข้า java.util.hashmap; นำเข้า java.util.hashset; นำเข้า java.util.list; นำเข้า cn.lulei.search.engine.model.sortbean; Serachbase คลาสสาธารณะ {// รายละเอียดจัดเก็บข้อมูลรายละเอียดของวัตถุการค้นหาโดยที่คีย์เป็นตัวระบุที่ไม่ซ้ำกันเพื่อแยกความแตกต่างของวัตถุ HashMap ส่วนตัว <String, Object> details = new HashMap <String, Object> (); // สำหรับคำหลักที่เข้าร่วมในการค้นหาพื้นที่จัดเก็บอาร์เรย์แบบเบาบางที่ใช้ที่นี่สามารถเก็บไว้ได้โดยใช้ HashMap รูปแบบคำจำกัดความมีดังนี้ // hashmap แบบคงที่ส่วนตัว <จำนวนเต็ม, hashset <string>> keysearch = new hashmap <จำนวนเต็ม, hashset <string >> (); // ค่าคีย์ของตัวกลาง HashMap นั้นเทียบเท่ากับตัวห้อยในอาร์เรย์แบบเบาบางและค่าเท่ากับค่าของอาร์เรย์กระจัดกระจายที่ตำแหน่งนี้ @suppresswarnings ("ไม่ได้ตรวจสอบ") Hashset ส่วนตัว <String> [] KeySearch = new HashSet [MaxLength]; / ***@คำอธิบาย: ใช้โหมด Singleton โดยใช้การกำหนดค่าเริ่มต้น on demand ที่ถือเพื่อโหลด*@เวอร์ชัน: 1.1.0*/ คลาสคงที่คลาส Lazyloadserachbase {ส่วนตัวคงที่ serachbase serachbase = ใหม่ serachbase (); } / *** โหมด Singleton ถูกตั้งค่าเป็นฟังก์ชั่นส่วนตัวที่นี่* / private serachbase () {} / *** @return* @description: รับ Singleton* / สาธารณะ serachbase serachbase getSerachbase () {return lazyloadserachbase.serachbase; } / ** * @param id * @return * @description: รับรายละเอียดตาม ID * / วัตถุสาธารณะ getObject (String id) {return details.get (id); } / ** * @param ids * @return * @description: รับรายละเอียดตาม IDs, แยก IDs ด้วย "," * / รายการสาธารณะ <Public> getObjects (ids สตริง) {ถ้า (ids == null || "" .equals (ids)) {return null; } รายการ <jobch> objs = new ArrayList <Object> (); String [] Idarray = ids.split (","); สำหรับ (String id: Idarray) {objs.add (getObject (id)); } return objs; } / ** * @param คีย์ * @return * @description: ค้นหารหัสที่เกี่ยวข้องตามคำค้นหาและใช้ "," เพื่อแยกระหว่าง IDs * / สตริงสาธารณะ getIds (คีย์สตริง) {ถ้า (key == null || "" .equals (คีย์)) {return null; } // find // idtimes เก็บว่าอักขระแต่ละตัวในคำค้นหาจะปรากฏใน ID ใน ID หรือไม่ idtimes = ใหม่ hashmap <สตริง, จำนวนเต็ม> idtimes = new hashmap <สตริง, จำนวนเต็ม> (); // ids เก็บรหัสของอักขระในคำค้นหา HashSet <String> ids = new HashSet <String> (); // การค้นหา (int i = 0; i <key.length (); i ++) {int at = key.charat (i); // ไม่มีอักขระที่สอดคล้องกันในคำค้นหา จากนั้นจับคู่อักขระถัดไปถ้า (keyesearch [ที่] == null) {ดำเนินการต่อ; } สำหรับ (Object OBJ: KeySearch [ที่] .toArray ()) {string id = (string) obj; int times = 1; if (ids.contains (id)) {times += idtimes.get (id); idtimes.put (id, ครั้ง); } else {ids.add (id); idtimes.put (id, ครั้ง); }}} // เรียงลำดับด้วยรายการอาร์เรย์ <SortBean> sortBeans = new ArrayList <SortBean> (); สำหรับ (String id: ids) {sortBean sortBean = new SortBean (); SortBeans.add (SortBean); SortBean.setId (ID); SortBean.settimes (idtimes.get (id)); } collections.sort (sortbeans, ตัวเปรียบเทียบใหม่ <SortBean> () {Public Int Compare (SortBean O1, SortBean O2) {return o2.getTimes () - o1.getTimes ();}}); // สร้าง return string Stringbuffer sb = new StringBuffer (); สำหรับ (sortBean sortBean: sortBeans) {sb.append (sortBean.getId ()); sb.append (","); } // ปล่อย idtimes.clear (); idtimes = null; ids.clear (); ids = null; sortbeans.clear (); sortBeans = null; // return return sb.toString (); } /** * @param id * @param searchkey * @param obj * @description: เพิ่มประวัติการค้นหา * /โมฆะสาธารณะเพิ่ม (String id, String searchkey, Object obj) {// พารามิเตอร์ว่างบางส่วนและไม่โหลดถ้า (id == null || searchkey == null || obj == null) } // บันทึก details.put (id, obj); // บันทึกคำค้นหา AddSearchKey (ID, SearchKey); }/** * @param id * @param searchkey * @description: เพิ่มคำค้นหาลงในโดเมนการค้นหา */โมฆะส่วนตัว addsearchkey (สตริงรหัส, สตริงค้นหาคีย์) {// พารามิเตอร์แยกต่างหากและไม่โหลด // นี่เป็นวิธีส่วนตัวและการตัดสินต่อไปนี้ } // ต่อไปนี้เป็นตัวละคร ที่นี่คุณสามารถใช้คำศัพท์คำอื่น ๆ ที่เป็นผู้ใหญ่สำหรับ (int i = 0; i <searchkey.length (); i ++) {// ค่าของ AT เทียบเท่ากับตัวห้อยของอาร์เรย์และ hashset ที่ประกอบด้วย id เทียบเท่ากับค่าของอาร์เรย์ int ที่ = searchkey.charat (i); if (keysearch [at] == null) {hashset <string> value = new HashSet <String> (); KeySearch [ที่] = ค่า; } keysearch [ที่] .add (id); - กรณีทดสอบ:
/ ** *@คำอธิบาย: */ แพ็คเกจ cn.lulei.search.engine.test; นำเข้า java.util.list; นำเข้า cn.lulei.search.engine.serachbase; การทดสอบระดับสาธารณะ {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {// วิธีการที่สร้างขึ้นอัตโนมัติ todo stub serachbase serachbase = serachbase.getserachbase (); serachbase.add ("1", "สวัสดี!", "สวัสดี!"); serachbase.add ("2", "สวัสดี! ฉันคือจางซาน", "สวัสดี! ฉันคือจางซาน"); serachbase.add ("3", "วันนี้อากาศดีมาก"); serachbase.add ("4", "คุณเป็นใคร", "คุณเป็นใคร"); serachbase.add ("5", "เรื่องของคณิตศาสตร์ขั้นสูงเป็นเรื่องยาก", "คณิตศาสตร์สูงเป็นเรื่องยากแน่นอน"); serachbase.add ("6", "ทดสอบ", "ด้านบนเป็นเพียงการทดสอบ"); string ids = serachbase.getIds ("คณิตศาสตร์สูงของคุณ"); System.out.println (ID); รายการ <jobch> objs = serachbase.getObjects (ids); if (objs! = null) {สำหรับ (object obj: objs) {system.out.println ((สตริง) obj); - ผลการทดสอบผลลัพธ์มีดังนี้:
5, 3, 2, 1, 4, ตัวเลขที่สูงขึ้นนั้นยากมาก วันนี้อากาศค่อนข้างดี สวัสดี! ฉันคือจางซาน สวัสดี! คุณเป็นใคร?
เครื่องมือค้นหาง่าย ๆ ดังกล่าวถือว่าเสร็จสมบูรณ์
คำถามที่ 1: คำว่าคำกริยาที่นี่ใช้คำกริยาของตัวละครซึ่งค่อนข้างดีในการจัดการภาษาจีน แต่มันอ่อนแอมากในการจัดการภาษาอังกฤษ
วิธีการปรับปรุง: ใช้วิธีการแบ่งส่วนคำที่ครบกำหนดในปัจจุบันเช่น Ikanalyzer, Standardanalyzer ฯลฯ ด้วยวิธีนี้โครงสร้างข้อมูลของ KeySearch จำเป็นต้องได้รับการแก้ไขซึ่งสามารถแก้ไขได้เป็น HashMap ส่วนตัว <String, String> [] KeySearch = new HashMap [maxlength]; ที่คีย์เก็บองค์ประกอบคำของชิ้นส่วนและค่าจะจัดเก็บรหัสตัวระบุที่ไม่ซ้ำกัน
คำถามที่ 2: เครื่องมือค้นหาที่นำมาใช้ในบทความนี้ไม่ได้กำหนดน้ำหนักสำหรับองค์ประกอบของคำเช่น Lucene แต่เพียงกำหนดว่าองค์ประกอบของคำจะปรากฏในวัตถุหรือไม่
วิธีการปรับปรุง: ยังไม่มี การเพิ่มการประมวลผลน้ำหนักทำให้โครงสร้างข้อมูลมีความซับซ้อนมากขึ้นดังนั้นจึงไม่ได้รับการประมวลผลในขณะนี้และการประมวลผลน้ำหนักจะถูกนำไปใช้ในบทความในอนาคต
มาแนะนำ แนวคิดการใช้งานของเครื่องมือค้นหา สั้น ๆ
ตั้งค่าคุณสมบัติทั้งสองของรายละเอียดและ KeySearch ในคลาส Serachbase รายละเอียดใช้เพื่อจัดเก็บข้อมูลโดยละเอียดของวัตถุและใช้ KeySearch เพื่อจัดทำดัชนีโดเมนการค้นหา รูปแบบข้อมูลรายละเอียดคือ HASHMAP และรูปแบบข้อมูลของ KeySearch เป็นอาร์เรย์ที่กระจัดกระจาย (สามารถเป็น HashMap ได้ค่าคีย์สื่อ HashMap นั้นเทียบเท่ากับตัวห้อยในอาร์เรย์กระจัดกระจายและค่าเท่ากับค่าของอาร์เรย์ที่กระจัดกระจายที่ตำแหน่งนี้)
ฉันจะไม่แนะนำรายละเอียดมากเกินไป
วิธีการคำนวณของตัวห้อยอาร์เรย์ใน KeySearch (เช่น HASHMAP คือคีย์) คือการได้รับอักขระตัวแรกค่า int ค่าขององค์ประกอบคำ (เพราะคำว่าคำนามในบทความนี้ใช้ตัวละครอนุภาคดังนั้นตัวละครจึงเป็นองค์ประกอบคำ) ค่า int คือตัวห้อยของอาร์เรย์และค่าอาร์เรย์ที่สอดคล้องกันเป็นตัวระบุเฉพาะของวัตถุ ด้วยวิธีนี้โครงสร้างข้อมูลของ KeySearch มีดังนี้
ดังนั้นเมื่อคุณต้องการเพิ่มระเบียนใหม่คุณจะต้องโทรหาวิธีเพิ่มเท่านั้น
ตรรกะการใช้งานสำหรับการค้นหาคล้ายกับ KeySearch ด้านบน สำหรับการค้นหา ID เพียงแค่ใช้วิธี GET ของ HashMap สำหรับการค้นหาคำค้นหากระบวนการโดยรวมยังใช้การแบ่งส่วนคำก่อนการสืบค้นวินาทีและเรียงลำดับล่าสุด แน่นอนคำว่าคำกริยาที่นี่ควรสอดคล้องกับคำที่ใช้ในการสร้าง (นั่นคือการใช้อนุภาคของอักขระเมื่อสร้างและมีการใช้อนุภาคของตัวละครเมื่อค้นหา)
ในเมธอด getIds, hashmap <string, integer> idtimes = new hashmap <string, integer> (); ตัวแปร idtimes ใช้เพื่อเก็บองค์ประกอบคำในคำค้นหาจะปรากฏใน Keyesearch ค่าคีย์คือ ID ตัวระบุที่ไม่ซ้ำกันและค่าคือจำนวนองค์ประกอบคำที่ปรากฏ HashSet <String> ids = new HashSet <String> (); ตัวแปร IDS ใช้เพื่อจัดเก็บ ID ของการเกิดขึ้นของคำ ความซับซ้อนของการค้นหาด้วยวิธีนี้คือจำนวนองค์ประกอบคำ n ของคำค้นหา รับรหัสที่มีองค์ประกอบคำสร้างอาร์เรย์ sortBean และเรียงลำดับ กฎการเรียงลำดับคือการลดลำดับของจำนวนองค์ประกอบคำ ในที่สุดสตริง IDS จะถูกส่งกลับและแต่ละ ID จะถูกหารด้วย "," หากคุณต้องการรับข้อมูลโดยละเอียดให้ใช้วิธีการ getObjects
ข้างต้นเป็นเพียงเครื่องมือค้นหาที่เรียบง่ายและไม่ได้ออกแบบวิธีการคำนวณมากเกินไป ฉันหวังว่ามันจะเป็นแรงบันดาลใจให้กับการเรียนรู้ของทุกคน