2010-02-09 61 views
5

Về cơ bản, những gì tôi đang tìm kiếm là một loại lớp hoặc phương pháp để thực hiện một từ điển trong PHP. Ví dụ, nếu tôi đang xây dựng một từ unscrambler - cho phép nói rằng tôi đã sử dụng các chữ cái 'a, e, l, p, p'. Số lượng khả năng sắp xếp là rất lớn - làm cách nào để tôi chỉ hiển thị những từ là từ thực tế (táo, nhạt ...)?Lớp từ điển PHP? hoặc thay thế?

Cảm ơn!

+4

Bạn có biết thực tế là trong PHP, bất kỳ mảng kết hợp nào có hiệu lực từ điển không? – amn

Trả lời

3

Các vấn đề tra cứu từ điển có thể được giải quyết một cách hiệu quả bằng cách sử dụng Trie.

Tôi khuyên bạn nên tìm danh sách từ, từ WordNet, lưu trữ trong Trie và sau đó thực hiện tra cứu nhanh các từ có thể.

Một giải pháp sẽ có dạng:

  1. tải các danh sách từ
  2. cửa hàng trong danh sách từ trong một Trie
  3. chấp nhận đầu vào cho một từ để xắp xếp lại
  4. thử hoán vị i = 1.N

    a. tra cứu hoán vị tôi sử dụng trie

    b. nếu có kết quả tích cực, hãy lưu trữ để hiển thị

    c. lặp (i ++)

  5. lặp lại từ 3.

chỉnh sửa:

Một mặt lưu ý ở đây là đối với bất kỳ ký tự từ chiều dài N có thể có N! tra cứu bắt buộc (cho 7 ký tự sẽ là 5040). Bạn nên xem xét thực hiện một số tối ưu hóa cho thuật toán tra cứu trie. Ví dụ, bạn đạt được hiệu quả đáng kể bằng cách loại bỏ các dữ liệu không hợp lệ sớm, và không lặp lại các hoán vị cuối.

ví dụ: với từ táo, nếu bạn có hoán vị nơi bạn đã chọn "ppl" làm ba ký tự đầu tiên, sẽ không tìm thấy từ nào. Vì vậy, không có vấn đề làm thế nào bạn permute a và e ở cuối bạn không thể xây dựng một từ.Chấm dứt sớm hoán vị có thể quan trọng đối với hiệu quả của thuật toán của bạn.

+0

Cảm ơn. Điều này làm cho tinh thần =) – Rohan

+0

Điều này không giúp đỡ với các từ tranh giành. Trước tiên, bạn phải bình thường hóa chúng như trong câu trả lời của zerkms –

+0

@Michael, không, bạn chỉ có thể thử tất cả các hoán vị. Kể từ khi Trie tra cứu sẽ cực kỳ nhanh chóng hình phạt cho việc tìm kiếm nhiều lần sẽ thấp; được cấp cho các chuỗi dài có thể có một số hoán vị lớn, và giải pháp này sẽ không có ý nghĩa với các từ lớn hơn nhiều so với nói, 7 ký tự –

0

Lưu danh sách các từ trong một tệp hoặc cơ sở dữ liệu, và sau đó chỉ cần thử tất cả các kết hợp. Bạn cũng có thể xem xét vị trí có khả năng của nguyên âm so với phụ âm để có khả năng tăng tốc nó. Thay vì tạo danh sách từ của riêng bạn, bạn có thể sử dụng một cái gì đó như WordNet.

+1

thú vị. Làm thế nào tôi có thể sử dụng WordNet với PHP? – Rohan

+0

Sẽ rất tuyệt nếu ai đó đưa ra lý do bỏ phiếu cho điều này. Dù sao, trả lời: http://wordnet.princeton.edu/wordnet/related-projects/#PHP –

3

Ah và câu trả lời khác:

Nếu bạn chỉ muốn có tất cả các từ thực - sau đó tìm bất kỳ từ điển lớn nào. sau đó lưu trữ theo cách:

từ | băm

nơi từ là từ bản thân và băm được sắp xếp theo thứ tự abc chữ:

cho băm táo sẽ là: aelpp hoặc aelp2

sau đó cho lá thư trao đi qua tất cả các kết hợp sử dụng algo tương tự cho băm và tìm kiếm thông qua cái bàn này.

+0

"băm" là từ sai. "key" sẽ tốt hơn - như sử dụng nó như một chìa khóa trong một hashtable. –

+0

đã đồng ý, "khóa" có liên quan hơn ở đây – zerkms

+0

Câu hỏi của tôi là, tôi lấy từ điển lớn này ở đâu? – Rohan

2

bạn cũng có thể xem xét pspell

http://php.net/manual/en/book.pspell.php

$ps = pspell_new("en"); 
foreach(array('alppe', 'plape', 'apple') as $word) 
    if(pspell_check($ps, $word)) 
     echo $word; 
+1

Kể từ PHP 5.3, pspell đã được thay thế bằng Enchant: http: //www.php .net/manual/en/book.enchant.php – Glacials

0

Tôi thực sự như giải pháp zerkms của tốt hơn nhưng đây là một số khác

tạo 2 bảng

words 
----- 
word_id (primary key) 
word 


letter_index 
----- 
letter (idx) 
word_id (idx) 

Khi bạn thêm một từ vào bảng từ bạn phải thêm một mục vào l etter_index cho mỗi chữ cái duy nhất. letter_index có khóa chính dựa trên cả chữ cái và word_id.
Để tìm các từ gồm một nhóm các chữ cái mà bạn tạo ra một cái gì đó truy vấn như:

SELECT word FROM words w 
// for each letter in the search 
INNER JOIN letter_index i ON (w.word_id = i.word_id AND i.letter = letter_1) 
INNER JOIN letter_index i ON (w.word_id = i.word_id AND i.letter = letter_2) 
INNER JOIN letter_index i ON (w.word_id = i.word_id AND i.letter = letter_3) 
... 
INNER JOIN letter_index i ON (w.word_id = i.word_id AND i.letter = letter_n) 
0

hay, bạn có thể sử dụng api developer.dictionary.com và chỉ cần làm một tra cứu từ để xác nhận. cũng có thể thực hiện kiểm tra chính tả.

Các vấn đề liên quan