أتذكر أن معلم Java قال ذات مرة سؤال مقابلة على Baidu ، وهو ما يعني تقريبًا "هناك 10000 سجل مضطربة ، وكيفية العثور بسرعة على السجلات التي تريدها منها". هذا يعادل محرك بحث بسيط. في الآونة الأخيرة ، لقد أدركت هذا بالفعل في العمل الذي قمت بفرزه هذا العام. اليوم سوف أشاطركم مزيد من تجريده.
أولا اكتب رمز التنفيذ المحدد ، وكتابة أفكار تنفيذ محددة ومنطق بعد الكود.
الفاصوليا المستخدمة للفرز أثناء البحث
/ ** *@الوصف: */ package cn.lulei.search.engine.model ؛ الفئة العامة SortBean {Private String ID ؛ أوقات خاصة السلسلة العامة getId () {معرف الإرجاع ؛ } public void setId (string id) {this.id = id ؛ } public int getTimes () {return times ؛ } public void Setimes (int times) {this.times = times ؛ }} بنية بيانات البحث التي تم إنشاؤها وخوارزمية البحث البسيطة
/ ** *@الوصف: */ package 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> التفاصيل = new hashmap <string ، Object> () ؛ // بالنسبة للكلمات الرئيسية المشاركة في البحث ، يمكن أيضًا تخزين تخزين الصفيف المتفرق المستخدم هنا باستخدام HashMap. تنسيق التعريف هو كما يلي // hashmap الثابتة الخاصة <integer ، hashset <string> keysearch = new hashmap <integer ، hashset <string> () ؛ . suppressWarnings ("غير محدد") التجزئة الخاصة <String> [] KeySearch = new hashset [maxLength] ؛ ] } / *** تم تعيين وضع Singleton على الوظيفة الخاصة هنا* / serachbase الخاص () {} / *** return* description: get singleton* / public static serachbase getSerachbase () {return lazyloadserachbase.serachbase ؛ } / ** * @param id * return * description: احصل على التفاصيل استنادًا إلى المعرف * / الكائن العام getObject (string id) {return details.get (id) ؛ } / ** * param ids * return * description: احصل على التفاصيل استنادًا إلى IDS ، افصل IDS مع "،" * / قائمة عامة <bount> getObjects (string ids) {if (ids == null || ".equals (ids)) {return null ؛ } قائمة <Object> objs = new ArrayList <Object> () ؛ String [] idarray = ids.split ("،") ؛ لـ (معرف السلسلة: idarray) {objs.add (getObject (id)) ؛ } إرجاع objs ؛ } / ** * @param key * return * description: ابحث عن المعرف المقابل وفقًا لمصطلحات البحث ، واستخدم "،" للانقسام بين IDS * / public string getIDS (مفتاح السلسلة) {if (key == null || ".equals (key)) {return null ؛ }. idtimes = new hashmap <string ، integer> idtimes = new hashmap <string ، integer> () ؛ // IDS يخزن معرف الأحرف في مصطلح البحث. hashset <string> ids = new hashset <string> () ؛ // finding لـ (int i = 0 ؛ i <key.length () ؛ i ++) {int at = key.charat (i) ؛ // لا يوجد حرف مقابل في مصطلح البحث. ثم تطابق الحرف التالي if (KeySearch [at] == null) {contert ؛ } لـ (Object OBJ: KeySearch [at] .toarray ()) {string id = (string) obj ؛ الأوقات الداخلية = 1 ؛ if (ids.contains (id)) {times += idtimes.get (id) ؛ idtimes.put (id ، times) ؛ } آخر {ids.add (id) ؛ idtimes.put (id ، times) ؛ }}} // الفرز باستخدام قائمة الصفيف <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 () ؛}}) ؛ // بناء string stringbuffer sb = new StringBuffer () ؛ لـ (sortbean sortbean: sortbeans) {sb.append (sortbean.getId ()) ؛ sb.append ("،") ؛ } // refer the 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 (string id ، string searchKey ، Object obj) {// المعلمات فارغة جزئيًا ولا يتم تحميلها إذا (id == null || searchKey == null || obj == null) {return ؛ } // حفظ تفاصيل الكائن. // حفظ مصطلح البحث AddSearchKey (ID ، SearchKey) ؛ }/** * param id * param searchkey * description: إضافة مصطلحات البحث إلى مجال البحث */private void addSearchKey (string id ، string searchkey) {// معلمات منفصلة فارغة ولم يتم تحميلها // هذه طريقة خاصة ، ويمكن إصدار الحكم التالي ، ولكن من أجل الحصول على محددات التصميم ، إذا (id = id = id == null == null) } // ما يلي هو النعت الحرف. هنا يمكنك أيضًا استخدام مشاركات الكلمات الناضجة الأخرى لـ (int i = 0 ؛ i <searchKey.Length () ؛ i ++) {// قيمة AT تعادل العاطفة من الصفيف ، و hashset المكونة من معرف تعادل قيمة الصفيف int at = searchKey.charat (i) ؛ if (keysearch [at] == null) {hashset <string> value = new hashset <string> () ؛ KeySearch [at] = value ؛ } keysearch [at] .add (id) ؛ }}} حالات الاختبار:
/ ** *@الوصف: */ package cn.lulei.search.engine.test ؛ استيراد java.util.list ؛ استيراد cn.lulei.search.engine.serachbase ؛ اختبار الفئة العامة {public static void main (string [] args) {// todo method method method tuto serachbase serachbase = serachbase.getserachbase () ؛ serachbase.add ("1" ، "Hello!" ، "Hello!") ؛ serachbase.add ("2" ، "مرحبًا! أنا Zhang San." ، "مرحبًا! أنا Zhang San.") ؛ serachbase.add ("3" ، "الطقس جيد جدا اليوم.") ؛ serachbase.add ("4" ، "من أنت؟" ، "من أنت؟") ؛ serachbase.add ("5" ، "موضوع الرياضيات المتقدمة أمر صعب" ، "الرياضيات العالية أمر صعب بالفعل.") ؛ serachbase.add ("6" ، "test" ، "ما سبق هو مجرد اختبار") ؛ معرفات السلسلة = serachbase.getids ("الرياضيات العالية") ؛ System.out.println (IDS) ؛ قائمة <Object> objs = serachbase.getObjects (IDS) ؛ if (objs! = null) {for (object obj: objs) {system.out.println ((string) obj) ؛ }}}} نتائج إخراج الاختبار هي كما يلي:
5 ، 3 ، 2 ، 1 ، 4 ، الأرقام الأعلى صعبة بالفعل. الطقس اليوم جيد جدا. مرحبًا! أنا تشانغ سان. مرحبًا! من أنت؟
يعتبر محرك البحث البسيط هذا مكتملًا.
السؤال 1: تستخدم كلمة النعت هنا Farhts Formle ، وهو أمر جيد جدًا في التعامل مع اللغة الصينية ، لكنه ضعيف جدًا في التعامل مع اللغة الإنجليزية.
طريقة التحسين: استخدم طريقة تجزئة الكلمات الناضجة الحالية ، مثل IkanAdyzer و StandardAnalyzer ، وما إلى ذلك ، وبهذه الطريقة ، يجب تعديل بنية بيانات المفاتيح ، والتي يمكن تعديلها إلى hashmap الخاص <string ، string> [] KeySearch = new hashmap [maxlength] ؛ حيث يقوم المفتاح بتخزين عنصر كلمة الجزء ، وتخزن القيمة معرف المعرف الفريد.
السؤال 2: لا يضع محرك البحث الذي تم تنفيذه في هذه المقالة أوزان لعناصر الكلمات مثل Lucene ، ولكن ببساطة يحدد ما إذا كانت عناصر الكلمات تظهر في الكائن.
طريقة التحسين: لا شيء بعد. إضافة معالجة الوزن تجعل بنية البيانات أكثر تعقيدًا ، لذلك لم تتم معالجتها في الوقت الحالي ، وسيتم تنفيذ معالجة الوزن في المقالات المستقبلية.
دعونا نقدم بإيجاز أفكار تنفيذ محركات البحث .
قم بتعيين خصائص التفاصيل و KeySearch في فئة Serachbase. يتم استخدام التفاصيل لتخزين المعلومات التفصيلية للكائن ، ويتم استخدام KeySearch لفهرسة مجال البحث. إن تنسيق بيانات التفاصيل هو hashmap ، وتنسيق بيانات المفاتيح هو صفيف متناثر (يمكن أن يكون أيضًا hashmap ، وقيمة مفتاح HashMap المتوسطة تعادل التراكمية في الصفيف المتناثر ، والقيمة تعادل قيمة المصفوفة المتناثرة في هذا الموضع).
لن أعطي الكثير من المقدمة للتفاصيل.
تتمثل طريقة الحساب للاشتراكات في Array في KeySearch (مثل HashMap هي المفتاح) هي الحصول على القيمة الأولى من الحرف int لعنصر الكلمة (لأن كلمة النعت في هذه المقالة تستخدم Forme Formle ، وبالتالي فإن الحرف هو عنصر كلمة). قيمة int هي فرقة الصفيف ، وقيمة الصفيف المقابلة هي المعرف الفريد للكائن. وبهذه الطريقة ، فإن بنية بيانات KeySearch هي كما يلي
لذلك ، عندما تريد إضافة سجل جديد ، تحتاج فقط إلى استدعاء طريقة إضافة.
يشبه منطق التنفيذ للبحث المفاتيح أعلاه. للبحث عن الهوية ، ما عليك سوى استخدام طريقة الحصول على HashMap. للبحث عن مصطلحات البحث ، تستخدم العملية الشاملة أيضًا تجزئة الكلمات أولاً ، والاستعلام الثاني ، وفرزها الأخير. بطبيعة الحال ، يجب أن تكون كلمة النعت هنا متسقة مع كلمة النعت المستخدمة لإنشاء (أي ، يتم استخدام مشاركة الأحرف عند الإنشاء ، ويتم استخدام الحرف أيضًا عند البحث).
في طريقة getIDs ، يتم استخدام hashmap <string ، integer> idtimes = new hashmap <string ، integer> () ؛ idtimes متغير لتخزين عدد عناصر الكلمات في مصطلح البحث في KeySearch. القيمة الرئيسية هي معرف المعرف الفريد والقيمة هي عدد عناصر الكلمات التي تظهر. hashset <string> ids = new hashset <string> () ؛ يتم استخدام متغير IDS لتخزين معرفات حدوث الكلمة. تعقيد البحث بهذه الطريقة هو عدد عناصر الكلمات في مصطلح البحث. الحصول على معرفات تحتوي على عناصر الكلمات ، وبناء صفيف Sortbean ، وفرزها. قاعدة الفرز هي ترتيب تنازلي لعدد عناصر الكلمات. أخيرًا ، يتم إرجاع سلسلة IDS ، ويتم تقسيم كل معرف على "،". إذا كنت ترغب في الحصول على معلومات مفصلة ، فاستخدم طريقة getObjects.
ما سبق هو مجرد محرك بحث بسيط ولم يصمم الكثير من طرق الحساب. آمل أن يلهم تعلم الجميع.