Cấu trúc dữ liệu hiệu quả để xây dựng trình kiểm tra chính tả nhanh


41

Tôi đang cố gắng viết một trình kiểm tra chính tả sẽ hoạt động với một từ điển khá lớn. Tôi thực sự muốn một cách hiệu quả để lập chỉ mục dữ liệu từ điển của tôi được sử dụng bằng khoảng cách Damerau-Levenshtein để xác định từ nào gần nhất với từ sai chính tả.

Tôi đang tìm kiếm một cấu trúc dữ liệu, người sẽ cho tôi sự thỏa hiệp tốt nhất giữa độ phức tạp không gian và độ phức tạp thời gian chạy.

Dựa trên những gì tôi tìm thấy trên internet, tôi có một vài khách hàng tiềm năng về loại cấu trúc dữ liệu sẽ sử dụng:

Trie

trie-500px

Đây là suy nghĩ đầu tiên của tôi và có vẻ khá dễ thực hiện và sẽ cung cấp tra cứu / chèn nhanh. Tìm kiếm gần đúng bằng Damerau-Levenshtein cũng nên đơn giản để thực hiện ở đây. Nhưng nó không có vẻ rất hiệu quả về độ phức tạp của không gian vì rất có thể bạn có rất nhiều chi phí với bộ lưu trữ con trỏ.

Patricia Trie

trie-500px

Điều này dường như tiêu tốn ít dung lượng hơn so với Trie thông thường vì về cơ bản bạn đang tránh chi phí lưu trữ con trỏ, nhưng tôi hơi lo lắng về sự phân mảnh dữ liệu trong trường hợp từ điển rất lớn như những gì tôi có.

Cây Suffix

hậu tố-500px

Tôi không chắc chắn về điều này, có vẻ như một số người thấy nó hữu ích trong việc khai thác văn bản, nhưng tôi không thực sự chắc chắn những gì nó sẽ mang lại về mặt hiệu suất cho trình kiểm tra chính tả.

Cây tìm kiếm Ternary

tst

Chúng trông khá đẹp và về độ phức tạp nên gần (tốt hơn?) Với Patricia Tries, nhưng tôi không chắc chắn về sự phân mảnh nếu nó tốt hơn tồi tệ hơn Patricia Tries.

Cây Burst

nổ

Đây có vẻ là một loại lai và tôi không chắc nó có lợi thế gì so với Tries và tương tự, nhưng tôi đã đọc nhiều lần rằng nó rất hiệu quả để khai thác văn bản.


Tôi muốn nhận được một số phản hồi về việc cấu trúc dữ liệu nào sẽ được sử dụng tốt nhất trong bối cảnh này và điều gì làm cho nó tốt hơn các cấu trúc khác. Nếu tôi thiếu một số cấu trúc dữ liệu, người thậm chí sẽ thích hợp hơn cho trình kiểm tra chính tả, tôi cũng rất quan tâm.


Làm thế nào để một patricia trie tránh chi phí lưu trữ con trỏ? Có phải chỉ là một en.wikipedia.org/wiki/Radix_tree ? Nếu đó là trường hợp, thì tôi nghĩ nó vẫn lưu trữ rất nhiều con trỏ, nhưng bạn sẽ tiết kiệm không gian rất lớn vì các tiền tố thông thường chỉ được lưu trữ một lần
Joe

n

1
@linker: Bạn đã thử tất cả các biến thể cho từ điển của bạn chưa? Với một trường hợp sử dụng cố định, đó có lẽ là cách nhanh nhất để tìm ra cơ sở hạ tầng nào tiêu tốn bao nhiêu dung lượng.
Raphael

1
Nó chỉ là một từ điển cơ bản, chỉ là một danh sách các từ được đánh vần chính xác.
Charles Menguy

Câu trả lời:


4

Tôi đã gặp cùng một vấn đề, nhưng có cách tiếp cận khác nhau. Bạn có thể xây dựng một số loại hàm "băm", từ này sẽ cho cùng một từ hoặc số gần.

Vấn đề là, chức năng đó sẽ cho kết quả "tốt" cho các từ có chèn / xóa, sẽ cho "xấu" khi chuyển đổi và ngược lại. Ví dụ: ánh xạ các chữ cái thành số, chữ cái tương tự với các số liền kề và chỉ tổng hợp chúng cho mỗi chữ cái trong từ. Sau đó tạo các bảng băm với các bộ cho mỗi khóa và tìm giao điểm cho từ.

Có thể một số kết quả có thể đạt được nếu chúng ta nhìn vào các từ "không gian". X để thay đổi chữ cái, Y để thêm / xóa, Z để chuyển tiếp hoặc đại loại như thế.

Tuy nhiên đây chỉ là những ý tưởng trừu tượng, tôi không có đủ thời gian để thực hiện chúng.


Đây là những gì Soundex thực hiện en.wikipedia.org/wiki/Soundex
rgrig

4

O(log(n))O

Không lưu trữ các chuỗi trong cây số liệu. Chỉ cần lưu trữ một chỉ mục và lưu trữ các chuỗi trong cây Patricia.

Tôi không chắc chắn bạn nên sử dụng cây nào. Nó sẽ phụ thuộc vào dữ liệu của bạn và yêu cầu của bạn (bạn có cần chèn nhanh không?). Cập nhật câu hỏi của bạn nếu bạn thấy rằng một cây hiệu quả hơn những cây khác.

Bạn cũng có thể nhìn vào các công cụ chuyên dụng, như lucene.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.