1. คำนำ
ในระหว่างการพัฒนาการส่งข้อความของผู้ใช้บางคนมักจะถูกประมวลผลดังนั้นจึงเกี่ยวข้องกับฟังก์ชั่นของการกรองคำที่ละเอียดอ่อน การใช้อัลกอริทึมเครื่อง DFA Finite State ในวัสดุอ้างอิงใช้เพื่อสร้างกราฟโดยตรง การกรองคำที่ละเอียดอ่อนและคำขวัญโฆษณาเสร็จสมบูรณ์และประสิทธิภาพนั้นดีดังนั้นแบ่งปัน
การใช้งานเฉพาะ:
1. การจับคู่การกรองเคส
2. จับคู่ตัวกรองครึ่งความกว้างเต็มความกว้าง
3. การจับกรองการกรองการกรองคำชั่วคราว
4. การกรองคำทำซ้ำสำหรับคำที่ละเอียดอ่อน
ตัวอย่างเช่น:
รองรับการตรวจจับการกรองประเภทต่อไปนี้:
มีเพศสัมพันธ์
คดีมีเพศสัมพันธ์
มีเพศสัมพันธ์ครึ่งความกว้างครึ่งความกว้าง
f !!! u & c ### k หยุดคำพูด
ffuuuuccccckkk คำทำซ้ำ
มีหลายวิธีในการกรองคำที่ละเอียดอ่อน ฉันจะอธิบายหลายประเภทที่ฉันเข้าใจตอนนี้:
①สอบถามคำที่ละเอียดอ่อนในฐานข้อมูลลูปคำที่ละเอียดอ่อนแต่ละคำจากนั้นค้นหาตั้งแต่ต้นจนจบในข้อความอินพุตเพื่อดูว่าคำที่ละเอียดอ่อนนี้มีอยู่หรือไม่
เพื่อให้มันตรงไปตรงมาวิธีนี้คือการหาวิธีจัดการกับอีกวิธีหนึ่ง
ข้อดี: ง่ายมาก โดยพื้นฐานแล้วมันไม่ยากที่จะนำไปใช้กับรหัส Java
ข้อเสีย: ประสิทธิภาพนี้ทำให้ฉันวิ่งมากกว่า 100,000 ม้าโคลนหญ้าในใจของฉันและการจับคู่นั้นเจ็บปวดเล็กน้อย? ถ้าเป็นภาษาอังกฤษคุณจะพบกับสิ่งที่พูดไม่ออกเช่นภาษาอังกฤษ
A เป็นคำที่ละเอียดอ่อน ถ้าฉันเป็นเอกสารภาษาอังกฤษมันต้องประมวลผลคำที่ละเอียดอ่อนกี่ครั้ง? มีใครบอกฉันได้ไหม
②อัลกอริทึม DFA ในตำนาน (Automata ที่ไม่ดี) เป็นสิ่งที่ฉันต้องการแบ่งปันกับคุณ ท้ายที่สุดมันให้ความรู้สึกทั่วไปมากขึ้น ฉันหวังว่าทุกคนสามารถตรวจสอบหลักการของอัลกอริทึมด้วยตัวเอง
ข้อมูลจะไม่ถูกอธิบายอย่างละเอียดที่นี่
ข้อดี: อย่างน้อยก็มีประสิทธิภาพมากกว่า SB ข้างต้น
ข้อเสีย: มันไม่ยากสำหรับผู้ที่ได้เรียนรู้อัลกอริทึม แต่ก็ไม่ยากที่จะใช้ มันเจ็บปวดเล็กน้อยที่จะเข้าใจประสิทธิภาพการจับคู่ไม่สูงและใช้หน่วยความจำ
ยิ่งคำที่อ่อนไหวมากเท่าไหร่หน่วยความจำก็ยิ่งกินมากขึ้นเท่านั้น
③ประเภทที่สามมีการอธิบายโดยเฉพาะที่นี่นั่นคือคุณควรเขียนอัลกอริทึมด้วยตัวเองหรือเพิ่มประสิทธิภาพตามอัลกอริทึมที่มีอยู่ นี่คือสิ่งที่เสี่ยวอลันแสวงหา
หนึ่งในอาณาจักรที่สูงหากพี่ชายคนใดมีความคิดของตัวเองอย่าลืม Xiao Alan คุณสามารถเพิ่ม QQ ของ Xiao Alan: 810104041 เพื่อสอน Xiao Alan สองเทคนิคให้เล่น
2. การใช้งานรหัส
โครงสร้างไดเรกทอรีมีดังนี้:
ในไดเรกทอรีทรัพยากร:
Stopwd.txt: หยุดชั่วคราวเวลาจับคู่จะถูกกรองโดยตรง
Wd.txt: อรรถาภิธานที่ละเอียดอ่อน
1. หมวดการกรองคำที่ละเอียดอ่อนของ WordFilter
แพ็คเกจ org.andy.sensitivewdfilter; นำเข้า java.io.bufferedreader; นำเข้า java.io.ioException; นำเข้า Java.io.InputStreamReader; นำเข้า java.util.arraylist; นำเข้า java.util.hashmap; นำเข้า java.util.hashset; นำเข้า java.util.list; นำเข้า java.util.map; นำเข้า java.util.set; นำเข้า org.andy.sensitivewdfilter.util.bcconvert; /** * เวลาการสร้าง: 30 สิงหาคม 2559 เวลา 3:01:12 น. * * ความคิด: สร้างตัวกรอง, แจกแจงว่าตัวอักษรทั้งหมดของ 0 ~ 65535 เริ่มต้นที่จุดเริ่มต้นของคำที่ละเอียดอ่อน * * พิจารณาว่าพวกเขาเริ่มต้นด้วยคำที่ละเอียดอ่อน | - มันโอเคที่จะได้รับโหนดหัว-คำต่อไปจากนั้นสำรวจทีละขั้นตอนอัลกอริทึม DFA * * @author Andy * @version 2.2 */ คลาสสาธารณะ WordFilter // เก็บคำแรกคำสุดท้ายของคำสแตติกสุดท้าย <จำนวนเต็ม, wordnode> nodes = new hashmap <จำนวนเต็ม, wordnode> (1024, 1); // ที่เก็บโหนดส่วนตัวชุดสุดท้ายคงที่ <integer> stopWdSet = new hashset <> (); // หยุดชั่วคราว Word Private Static Final CHAR SIGN = '*'; // การกรองคำที่ละเอียดอ่อนแทนที่ {ลอง {long a = system.nanotime (); init (); a = system.nanotime () - a; System.out.println ("เวลาโหลด:" + a + "ns"); System.out.println ("เวลาในการโหลด:" + a / 1000000 + "MS"); } catch (exception e) {โยน runtimeException ใหม่ ("ตัวกรองการเริ่มต้นล้มเหลว"); }} โมฆะคงที่ส่วนตัว init () {// รับคำที่ละเอียดอ่อนที่มีความรู้สึกไว (readwordFromFile ("wd.txt")); addstopword (readwordfromfile ("stopwd.txt")); } / ** * เพิ่มคำที่ละเอียดอ่อน * @param path * @return * / รายการคงที่ส่วนตัว <String> readwordFromFile (เส้นทางสตริง) {รายการ <String> คำ; bufferedReader br = null; ลอง {br = ใหม่ bufferedReader (ใหม่ inputStreamReader (wordFilter.class.getClassLoader (). getResourceasstream (เส้นทาง))); Words = new ArrayList <String> (1200); สำหรับ (String buf = ""; (buf = br.readline ())! = null;) {ถ้า (buf == null || buf.trim (). เท่ากับ ("")) ดำเนินการต่อ; Words.add (buf); }} catch (exception e) {โยน runtimeException ใหม่ (e); } ในที่สุด {ลอง {ถ้า (br! = null) br.close (); } catch (ioexception e) {}} คำกลับ; } / ** * เพิ่มคำหยุดชั่วคราว * * @param Words * / Void addstopword ส่วนตัว (รายการสุดท้าย <string> คำ) {ถ้า (คำ! = null && words.size ()> 0) {char [] chs; สำหรับ (String Curr: Words) {CHS = CURR.TOCHARARRAY (); สำหรับ (char c: chs) {stopwdset.add (charconvert (c)); }}}}} / *** เพิ่ม dfa node* @param words* / โมฆะคงที่ส่วนตัว addSensitiveWord (รายการสุดท้าย <String> คำ) {ถ้า (คำ! = null && words.size ()> 0) {char [] chs; int fchar; Int LastIndex; WordNode fnode; // โหนดตัวอักษรตัวแรกสำหรับ (String Curr: Words) {CHS = CURR.TOCHARARRAY (); fchar = charconvert (chs [0]); if (! set.contains (fchar)) {// ไม่มีคำจำกัดความเริ่มต้น set.add (fchar); // การตั้งค่าสถานะแรกสามารถเพิ่มซ้ำได้ อย่างไรก็ตามมันถูกตัดสินดังนั้นมันจะไม่ซ้ำ fnode = new wordNode (fchar, chs.length == 1); NOODES.PUT (FCHAR, FNODE); } else {fnode = nodes.get (fchar); if (! fnode.islast () && chs.length == 1) fnode.setLast (จริง); } lastIndex = chs.length - 1; สำหรับ (int i = 1; i <chs.length; i ++) {fnode = fnode.addifnoexist (charconvert (chs [i]), i == LastIndex); }}}} / ** * การปรับการตัดสินแปลงคำที่ละเอียดอ่อนเป็นคำสวมหน้ากาก * @param src * @return * / สตริงสุดท้ายคงที่ dofilter (สตริงสุดท้าย src) {char [] chs = src.tochararray (); ความยาว int = chs.length; int currc; int k; โหนด WordNode; สำหรับ (int i = 0; i <length; i ++) {currc = charconvert (chs [i]); if (! set.contains (currc)) {ดำเนินการต่อ; } node = nodes.get (currc); // วันที่ 2 ถ้า (node == null) // จริง ๆ แล้วมันจะไม่เกิดขึ้นคุณเคยเขียนมันในความต่อเนื่อง; บูลีน canmark = false; int marknum = -1; if (node.islast ()) {// การจับคู่คำเดียว (วัน) canmark = true; Marknum = 0; } // ดำเนินการต่อ (วัน/วัน) ด้วยลำดับความสำคัญระยะยาว // you-3 sister-4 สามี -5 k = i; สำหรับ (; ++ k <length;) {int temp = charconvert (chs [k]); ถ้า (stopwdset.contains (temp))) ดำเนินการต่อ; node = node.QuerySub (temp); ถ้า (node == null) // ไม่มีการหยุดพัก; if (node.islast ()) {canmark = true; marknum = k - i; // 3-2}} ถ้า (canmark) {สำหรับ (k = 0; k <= marknum; k ++) {chs [k+i] = เครื่องหมาย; } i = i + marknum; }} ส่งคืนสตริงใหม่ (CHS); } / ** * คำที่ละเอียดอ่อนมี * @param src * @return * / public public boolean สุดท้าย isContains (สตริงสุดท้าย src) {char [] chs = src.tochararray (); ความยาว int = chs.length; int currc; int k; โหนด WordNode; สำหรับ (int i = 0; i <length; i ++) {currc = charconvert (chs [i]); if (! set.contains (currc)) {ดำเนินการต่อ; } node = nodes.get (currc); // วันที่ 2 ถ้า (node == null) // มันไม่เกิดขึ้นมันถูกเขียนขึ้นอยู่กับการดำเนินการต่อ บูลีน canmark = false; if (node.islast ()) {// การจับคู่คำเดียว (วัน) canmark = true; } // ดำเนินการต่อ (วันที่คุณ/วันน้องสาวของคุณ) โดยมีลำดับความสำคัญของอายุยืน // you-3 sister-4 สามี -5 k = i; สำหรับ (; ++ k <length;) {int temp = charconvert (chs [k]); ถ้า (stopwdset.contains (temp))) ดำเนินการต่อ; node = node.QuerySub (temp); ถ้า (node == null) // ไม่มีการหยุดพัก; if (node.islast ()) {canmark = true; }} ถ้า (canmark) {return true; }} return false; } / ** * uppercase เป็นตัวพิมพ์เล็กการแปลงเต็มความกว้างเป็นครึ่งความกว้าง * * @param src * @return * / ส่วนตัวคงที่ int charconvert (ถ่าน src) {int r = bcconvert.qj2bj (src); return (r> = 'a' && r <= 'z')? r + 32: r; - ใน:
IsContains: จะรวมคำที่ละเอียดอ่อน
Dofilter: คำที่ไวต่อกรอง
2. WordNode Word Word Word
แพ็คเกจ org.andy.sensitivewdfilter; นำเข้า java.util.linkedList; นำเข้า java.util.list; / ** * สร้างขึ้น: 30 สิงหาคม 2559 เวลา 3:07:45 น. * * @author Andy * @version 2.2 */ คลาสสาธารณะ WordNode {ค่า int ส่วนตัว; // ชื่อโหนดรายการส่วนตัว <WordNode> subnodes; // โหนดเด็กบูลีนส่วนตัว iSlast; // ค่าเริ่มต้นคำศัพท์สาธารณะเท็จ (ค่า int) {this.value = value; } public wordNode (ค่า int, boolean islast) {this.value = value; this.islast = iSlast; } / ** * * @param subnode * @return เป็น subnode subnode * / private wordNode addSubNode (สุดท้าย WordNode subnode) {ถ้า (subnodes == null) subnodes = new LinkedList <wordNode> (); subnodes.add (subnode); ส่งคืน subnode; } /*** หากมีให้ส่งคืนโหนดลูกโดยตรง หากไม่มีให้สร้างและเพิ่มและส่งคืนโหนดลูก * * @param value * @return */ public wordnode addifnoexist (ค่า int สุดท้าย, บูลีนสุดท้ายบูลีน islast) {ถ้า (subnodes == null) {return addSubnode } สำหรับ (wordNode subnode: subnodes) {if (subnode.value == ค่า) {ถ้า (! subnode.islast && islast) subnode.islast = true; ส่งคืน subnode; }} return addSubNode (new wordNode (value, iSlast)); } public wordNode querySub (ค่า int สุดท้าย) {ถ้า (subnodes == null) {return null; } สำหรับ (wordNode subnode: subnodes) {if (subnode.value == ค่า) ส่งคืน subnode; } return null; } บูลีนสาธารณะ Islast () {return islast; } โมฆะสาธารณะ setLast (บูลีน iSlast) {this.islast = iSlast; } @Override public int hashCode () {ค่าส่งคืน; -3. ผลการทดสอบ
โครงการรวมถึงอรรถาภิธานที่มีความละเอียดอ่อน, ซอร์สโค้ด, ลูกอรรถาภิธานหยุดชั่วคราว ฯลฯ เพียงเรียกใช้แพ็คเกจ Maven และ Jar เพื่อทำงานโดยตรง
ซอร์สโค้ดโครงการ: SensitiveWd-filter_jb51.rar
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น