2012-02-13 41 views
7

Tôi đang thử nghiệm triển khai metaphone cho C# và so sánh kết quả của nó với hàm metaphone() dựng sẵn từ PHP. Tuy nhiên, tôi đã đi qua một lỗi (đó là previously documented in PHP's issue tracker và thảo luận về a mailing list), nhưng tôi đang cố gắng để hiểu mã C đằng sau lỗi của họ vì lợi ích cá nhân của riêng tôi.Lỗi triển khai thực hiện metaphone PHP

Về cơ bản, theo thuật toán metaphone, hầu hết các trường hợp của -gh- phải được hiển thị im lặng. Trong trường hợp kiểm tra cụ thể của "wright", tôi mong đợi (và tạo bằng thuật toán của riêng tôi), khóa metaphone của "RT"

"wr" => R 
"i" => ignored 
"gh" => ignored 
"t" => T 

Result: RT 

Tuy nhiên, hàm metaphone của PHP trả về RFT. Rõ ràng, nó chuyển đổi -gh- thành một F, như thể nó ở cuối một từ (ví dụ "thô"), nhưng trong trường hợp của từ "wright", điều này là không chính xác, bởi vì -gh- không đến cuối từ. Nhìn vào các tập tin metaphone.c trong việc phân phối nguồn PHP, tôi nhìn thấy một vài điều quan trọng:

/* These prevent GH from becoming F */ 
#define NOGHTOF(c) (ENCODE(c) & 16) /* BDH */ 

... 

/* Go N letters back. */ 
#define Look_Back_Letter(n) (w_idx >= n ? toupper(word[w_idx-n]) : '\0') 

Và sau đó trên đường dây 342:

case 'G': 
    if (Next_Letter == 'H') { 
     if (!(NOGHTOF(Look_Back_Letter(3)) || Look_Back_Letter(4) == 'H')) { 
      Phonize('F'); 
      skip_letter++; 

Có thể ai đó giúp tôi hiểu những gì chính xác chức năng NOGHTOF hiện tại và tại sao mã này không chính xác hiển thị F cho -gh- trong "wright"? Tôi không thực sự là một anh chàng C, vì vậy mã không rõ ràng với tôi.

+1

Sau đó, có lẽ ai đó có thể gửi bản vá cho danh sách và sửa lỗi này! –

+0

SO cần thêm câu hỏi như thế này :) –

Trả lời

1

Ý nghĩa của NOGHTOF(c) là thực sự xác định bởi mã bắt đầu từ dòng 81:

char _codes[26] = { 
     1, 16, 4, 16, 9, 2, 4, 16, 9, 2, 0, 2, 2, 2, 1, 4, 0, 2, 4, 4, 1, 0, 0, 0, 8, 0 
    /* a b c d e f g h i j k l m n o p q r s t u v w x y z */ 
}; 

#define ENCODE(c) (isalpha(c) ? _codes[((toupper(c)) - 'A')] : 0) 

Về cơ bản, một giá trị được gán cho mỗi chữ cái của bảng chữ cái theo thứ tự (A = 1, B = 16, vv .) Sau đó, ENCODE macro kiểm tra xem ký tự được truyền là một chữ cái hay không; nếu có, nó trả về mã tương ứng cho chữ cái đó, ngược lại nó trả về ký tự null. (Nó không thực sự trở lại bất cứ điều gì, vì đây là một vĩ mô và được thay thế bởi trình biên dịch tại thời gian biên dịch để thay thế cuộc gọi thực tế.)

Cách tôi đang đọc mã cho 'G' là điều này (mà không cần cố gắng hiểu lý do tại sao):

If current letter is G then 
    If next letter is H then 
     Take "_code" value of a letter three letters back (why?) from the _codes table and check the fifth bit (from the back, naturally) 
     If this bit is not set OR if a letter four letters back (why?) is 'H' then 
      Add 'F' to the result 
      skip one more character (letter 'H' following the 'G') 

Tại sao nó giống như vậy, tôi chắc rằng ai đó có lý do chính đáng để viết theo cách này, nhưng có vẻ như một lỗi rõ ràng đối với tôi.

+0

Cảm ơn. Tôi chỉ hơi quen thuộc với các nhà khai thác cấp bit. Bạn có thể cho tôi biết chính xác 'AND'ing một số với 16 xóa 4 bit cuối cùng không? – Chris

+0

Đầu tiên, sai lầm của tôi, nó không xóa 4 bit cuối cùng - nó kiểm tra xem bit thứ năm được thiết lập - tôi đang cập nhật câu trả lời của tôi. Bây giờ, bạn không giao dịch với bất kỳ số nào, nhưng chỉ với một byte (8 bit): xxxxxxxx trong nhị phân; 16 ở dạng nhị phân là 00010000; Bây giờ bitwise AND lấy bit tương ứng của hai số và tạo một số mới bằng cách đặt bit tương ứng thành 1 chỉ khi cả hai bit là 1. –

+0

Phải, tôi đã nhận được toán tử & điều gì. Tôi đoán nó đã được kiểm tra để xem nếu bit 5 đã được thiết lập, nhưng đã bị nhầm lẫn bởi câu trả lời của bạn. Cám ơn giải thích rõ ràng. Có nói rằng, có, tôi cũng rất không chắc chắn tại sao kiểm tra xem lá thư thứ ba trước khi G là ('B', 'D', 'H') sẽ làm cho -gh im lặng. Có lẽ có coder ban đầu đã nhắm mục tiêu một vài từ chọn theo cách này (bột và bột tôi nhận được, nhưng hough?), Nhưng không có nghi ngờ mã là không chính xác/lỗi như địa ngục. Cảm ơn thông tin chi tiết bổ sung. – Chris

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