โครงสร้างข้อมูลที่มีประสิทธิภาพสำหรับการสร้างเครื่องมือตรวจสอบการสะกดคำอย่างรวดเร็ว


41

ฉันกำลังพยายามเขียนตัวตรวจการสะกดซึ่งควรใช้กับพจนานุกรมที่มีขนาดค่อนข้างใหญ่ ฉันต้องการวิธีที่มีประสิทธิภาพในการจัดทำดัชนีข้อมูลพจนานุกรมของฉันโดยใช้ระยะทางDamerau-Levenshteinเพื่อกำหนดว่าคำใดที่ใกล้เคียงที่สุดกับคำที่สะกดผิด

ฉันกำลังมองหาโครงสร้างข้อมูลที่จะให้ความประนีประนอมระหว่างความซับซ้อนของพื้นที่กับความซับซ้อนของรันไทม์ได้ดีที่สุด

จากสิ่งที่ฉันพบบนอินเทอร์เน็ตฉันมีโอกาสในการขายไม่กี่เกี่ยวกับประเภทของโครงสร้างข้อมูลที่จะใช้:

Trie

Trie-500px

นี่เป็นความคิดแรกของฉันและดูใช้งานได้ง่ายและควรมีการค้นหา / แทรกอย่างรวดเร็ว การค้นหาโดยประมาณโดยใช้ Damerau-Levenshtein ควรง่ายต่อการใช้งานที่นี่เช่นกัน แต่มันไม่ได้ดูมีประสิทธิภาพมากนักในแง่ของความซับซ้อนของพื้นที่เนื่องจากคุณมักจะมีค่าใช้จ่ายจำนวนมากกับที่เก็บข้อมูลพอยน์เตอร์

Patricia Trie

Trie-500px

ดูเหมือนว่าจะใช้เนื้อที่น้อยกว่า Trie ปกติเนื่องจากคุณไม่ต้องเสียค่าใช้จ่ายในการเก็บพอยน์เตอร์ แต่ฉันกังวลเกี่ยวกับการแยกส่วนข้อมูลในกรณีที่พจนานุกรมมีขนาดใหญ่มากเหมือนที่ฉันมี

ต้นไม้ต่อท้าย

คำต่อท้าย-500px

ฉันไม่แน่ใจเกี่ยวกับสิ่งนี้ดูเหมือนว่าบางคนจะพบว่ามีประโยชน์ในการทำเหมืองข้อความ แต่ฉันไม่แน่ใจว่าสิ่งที่จะให้ในแง่ของประสิทธิภาพสำหรับตัวตรวจสอบการสะกด

Ternary Search Tree

ทีเอสที

สิ่งเหล่านี้ดูดีมากและในแง่ของความซับซ้อนควรอยู่ใกล้ (ดีกว่า) กับ Patricia Tries แต่ฉันไม่แน่ใจเกี่ยวกับการแยกส่วนหากมันจะดีกว่าแย่กว่า Patricia Tries

ต้นไม้ระเบิด

ระเบิด

ดูเหมือนว่าจะเป็นลูกผสมและฉันก็ไม่แน่ใจว่าจะได้ประโยชน์อะไรจาก Tries และสิ่งที่คล้ายกัน แต่ฉันได้อ่านมาหลายครั้งแล้วว่ามันมีประสิทธิภาพมากสำหรับการทำเหมืองข้อความ


ฉันต้องการรับความคิดเห็นเกี่ยวกับโครงสร้างข้อมูลที่ดีที่สุดที่จะใช้ในบริบทนี้และสิ่งที่ทำให้ดีกว่าที่อื่น หากฉันขาดโครงสร้างข้อมูลบางอย่างที่เหมาะสมกว่าสำหรับเครื่องตรวจการสะกดคำฉันก็สนใจเช่นกัน


Triric ของ patricia จะหลีกเลี่ยงค่าใช้จ่ายในการเก็บพอยน์เตอร์ได้อย่างไร? มันเป็นแค่en.wikipedia.org/wiki/Radix_treeหรือเปล่า? หากเป็นเช่นนั้นฉันคิดว่ามันยังคงเก็บพอยน์เตอร์จำนวนมาก แต่คุณจะประหยัดพื้นที่ได้มากเพราะคำนำหน้าทั่วไปจะถูกเก็บไว้เพียงครั้งเดียว
Joe

n

1
@linker: คุณลองใช้พจนานุกรมทั้งหมดของคุณหรือยัง เมื่อพิจารณาถึงกรณีการใช้งานคงที่นั่นอาจเป็นวิธีที่เร็วที่สุดในการค้นหาว่าโครงสร้างข้อมูลใดกินพื้นที่เท่าใด
Raphael

1
มันเป็นพจนานุกรมพื้นฐานเพียงรายการรู้จักคำสะกดที่ถูกต้อง
Charles Menguy

คำตอบ:


4

ฉันพบปัญหาเดียวกัน แต่ใช้วิธีการที่แตกต่างกัน คุณสามารถสร้างฟังก์ชัน "hash" บางชนิดซึ่งสำหรับคำที่คล้ายกันจะให้หมายเลขเดียวกันหรือใกล้เคียง

ปัญหาคือฟังก์ชั่นที่จะให้ผลลัพธ์ "ดี" สำหรับคำที่มีการแทรก / ลบจะให้ "เลวร้าย" สำหรับการเปลี่ยนแปลงและในทางกลับกัน ตัวอย่าง: แมปตัวอักษรกับตัวเลขตัวอักษรที่คล้ายกันกับตัวเลขที่อยู่ติดกันและรวมไว้สำหรับตัวอักษรทุกตัวในคำ จากนั้นสร้างตารางแฮชพร้อมชุดสำหรับแต่ละคีย์และค้นหาจุดตัดสำหรับคำ

อาจเป็นผลลัพธ์บางอย่างที่สามารถทำได้ถ้าเราดูที่ "space" ของคำ X สำหรับการเปลี่ยนตัวอักษร, Y สำหรับการเพิ่ม / ลบ, Z สำหรับการเปลี่ยนแปลงหรืออะไรทำนองนั้น

อย่างไรก็ตามนี่เป็นเพียงแนวคิดที่เป็นนามธรรมฉันไม่มีเวลามากพอที่จะทำให้สำเร็จ


นี่คือสิ่งที่ Soundex ทำen.wikipedia.org/wiki/Soundex
rgrig

4

O(log(n))O

อย่าเก็บสตริงไว้ในแผนผังเมตริก เพียงแค่จัดทำดัชนีและเก็บสายอักขระไว้ในแผนผัง Patricia

ฉันไม่แน่ใจว่าคุณควรใช้ต้นไม้ชนิดใด มันจะขึ้นอยู่กับข้อมูลและความต้องการของคุณ (คุณต้องการแทรกเร็วหรือไม่) อัปเดตคำถามของคุณหากคุณพบว่าต้นไม้หนึ่งต้นมีประสิทธิภาพมากกว่าต้นไม้ต้นอื่น

คุณอาจดูเครื่องมือพิเศษเช่น lucene

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.