2012-02-13 10 views
7

मैं सी # के लिए मेटाफोन कार्यान्वयन का परीक्षण कर रहा हूं और PHP से अंतर्निहित मेटाफोन() फ़ंक्शन के विरुद्ध इसके परिणामों की तुलना कर रहा हूं। हालांकि, मैं एक बग में आया हूं (जो previously documented in PHP's issue tracker है और a mailing list पर चर्चा की गई), लेकिन मैं अपनी व्यक्तिगत रुचि के लिए अपने बग के पीछे सी कोड को समझने की कोशिश कर रहा हूं।PHP मेटाफोन कार्यान्वयन बग

मूल रूप से, मेटाफोन एल्गोरिदम के अनुसार, अधिकांश उदाहरणों को चुप किया जाना चाहिए। "राइट" की विशेष परीक्षा मामले में, मुझे उम्मीद है (और मेरे अपने एल्गोरिथ्म के साथ उत्पन्न) "आरटी" की एक metaphone कुंजी

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

Result: RT 

हालांकि, PHP के metaphone समारोह आरएफटी देता है। जाहिर है, यह एक एफ को परिवर्तित कर रहा है, जैसे कि यह एक शब्द (जैसे "मोटा") के अंत में था, लेकिन "wright" शब्द के मामले में, यह गलत है, क्योंकि -gh- करता है शब्द के अंत में नहीं आते हैं।

/* 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') 

और फिर लाइन 342 पर: पीएचपी स्रोत वितरण में metaphone.c फ़ाइल को देखते हुए, मैं कुछ महत्वपूर्ण चीजों को देखने के

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

किसी की मदद कर सकते हैं मुझे समझने वास्तव में क्या NOGHTOF समारोह क्या और यह कोड "wright" में गलत तरीके से एफ को प्रतिपादित क्यों कर रहा है? मैं वास्तव में एक सी लड़का नहीं हूं, इसलिए कोड मुझे बिल्कुल स्पष्ट नहीं है।

+1

तो शायद कोई सूची में पैच सबमिट कर सकता है और यह बग तय कर सकता है! –

+0

SO इस तरह के अधिक प्रश्नों की आवश्यकता है :) –

उत्तर

1

NOGHTOF(c) का अर्थ वास्तव में लाइन 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) 

अनिवार्य रूप से, एक मूल्य के वर्णमाला के प्रत्येक अक्षर के लिए असाइन किया गया है (एक = 1, बी = 16, आदि ।) फिर ENCODE मैक्रो जांच करता है कि पारित चरित्र एक पत्र है; यदि हां, तो वह उस पत्र के लिए संबंधित कोड देता है, अन्यथा यह null चरित्र देता है। (यह वास्तव में कुछ भी वापस नहीं करता है, क्योंकि यह एक मैक्रो है और वास्तविक कॉल को प्रतिस्थापित करने के लिए संकलन समय पर संकलक द्वारा प्रतिस्थापित किया जाता है।)

जिस तरह से मैं 'G' के लिए कोड पढ़ रहा हूं यह है (बिना प्रयास किए क्यों):

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') 

क्यों इसे इस तरह है, हालांकि मुझे परे है, मैं काफी यकीन है कि किसी को यह इस तरह से लिखने के लिए उचित कारण रहा हूँ, लेकिन यह मेरे लिए एक स्पष्ट बग लगती है।

+0

धन्यवाद। मैं थोड़ा सा स्तर ऑपरेटर के साथ कुछ हद तक परिचित हूँ। क्या आप मुझे बता सकते हैं कि आखिरकार 4 बिट्स के साथ 16 नंबरों को कैसे हटाया जा सकता है? – Chris

+0

सबसे पहले, मेरी गलती, यह पिछले 4 बिट को साफ़ नहीं कर रहा है - यह जांचता है कि पांचवां बिट सेट है या नहीं - मैं अपना जवाब अपडेट कर रहा हूं। अब, आप किसी भी संख्या से निपट नहीं रहे हैं, लेकिन केवल एक बाइट (8 बिट्स) के साथ: बाइनरी में xxxxxxxx; 16 बाइनरी में 00010000 है; अब थोड़ा सा और दो संख्याओं के संबंधित बिट्स लेता है और संबंधित बिट को केवल 1 तक सेट करके एक नया नंबर बना देता है यदि दोनों बिट्स हैं 1. –

+0

ठीक है, मुझे यह मिला कि ऑपरेटर क्या करता है। मुझे लगा कि यह देखने के लिए जांच कर रहा था कि बिट 5 सेट किया गया था, लेकिन आपके जवाब से उलझन में था। इसे साफ करने के लिए धन्यवाद। ऐसा कहकर, हाँ, मैं भी यह सुनिश्चित नहीं कर रहा हूं कि जी से पहले तीसरा अक्षर क्या है ('बी', 'डी', 'एच') - चुपचाप प्रस्तुत करेगा। शायद मूल कोडर इस तरह से कुछ चुनिंदा कुछ शब्दों को लक्षित कर रहा था (आटा और आटा मुझे मिलता है, लेकिन आटा?), लेकिन इसमें कोई संदेह नहीं है कि कोड नरक के रूप में गलत/छोटी है। अतिरिक्त अंतर्दृष्टि के लिए धन्यवाद। – Chris

संबंधित मुद्दे