سؤال

هذا الموقع يقدم "خوارزمية Schinke Latin Crateming" للتنزيل لاستخدامها في كرة الثلج نظام التنقي.

أريد استخدام هذه الخوارزمية ، لكنني لا أريد استخدام كرة الثلج.

الشيء الجيد: هناك بعض الكود الكاذب في تلك الصفحة التي يمكنك ترجمتها إلى وظيفة PHP. هذا ما جربته:

<?php
function stemLatin($word) {
    // output = array(NOUN-BASED STEM, VERB-BASED STEM)
    // DEFINE CLASSES BEGIN
    $queWords = array('atque', 'quoque', 'neque', 'itaque', 'absque', 'apsque', 'abusque', 'adaeque', 'adusque', 'denique', 'deque', 'susque', 'oblique', 'peraeque', 'plenisque', 'quandoque', 'quisque', 'quaeque', 'cuiusque', 'cuique', 'quemque', 'quamque', 'quaque', 'quique', 'quorumque', 'quarumque', 'quibusque', 'quosque', 'quasque', 'quotusquisque', 'quousque', 'ubique', 'undique', 'usque', 'uterque', 'utique', 'utroque', 'utribique', 'torque', 'coque', 'concoque', 'contorque', 'detorque', 'decoque', 'excoque', 'extorque', 'obtorque', 'optorque', 'retorque', 'recoque', 'attorque', 'incoque', 'intorque', 'praetorque');
    $suffixesA = array('ibus, 'ius, 'ae, 'am, 'as, 'em', 'es', ia', 'is', 'nt', 'os', 'ud', 'um', 'us', 'a', 'e', 'i', 'o', 'u');
    $suffixesB = array('iuntur', 'beris', 'erunt', 'untur', 'iunt', 'mini', 'ntur', 'stis', 'bor', 'ero', 'mur', 'mus', 'ris', 'sti', 'tis', 'tur', 'unt', 'bo', 'ns', 'nt', 'ri', 'm', 'r', 's', 't');
    // DEFINE CLASSES END
    $word = strtolower(trim($word)); // make string lowercase + remove white spaces before and behind
    $word = str_replace('j', 'i', $word); // replace all <j> by <i>
    $word = str_replace('v', 'u', $word); // replace all <v> by <u>
    if (substr($word, -3) == 'que') { // if word ends with -que
        if (in_array($word, $queWords)) { // if word is a queWord
            return array($word, $word); // output queWord as both noun-based and verb-based stem
        }
        else {
            $word = substr($word, 0, -3); // remove the -que
        }
    }
    foreach ($suffixesA as $suffixA) { // remove suffixes for noun-based forms (list A)
        if (substr($word, -strlen($suffixA)) == $suffixA) { // if the word ends with that suffix
            $word = substr($word, 0, -strlen($suffixA)); // remove the suffix
            break; // remove only one suffix
        }
    }
    if (strlen($word) >= 2) { $nounBased = $word; } else { $nounBased = ''; } // add only if word contains two or more characters
    foreach ($suffixesB as $suffixB) { // remove suffixes for verb-based forms (list B)
        if (substr($word, -strlen($suffixA)) == $suffixA) { // if the word ends with that suffix
            switch ($suffixB) {
                case 'iuntur', 'erunt', 'untur', 'iunt', 'unt': $word = substr($word, 0, -strlen($suffixB)).'i'; break; // replace suffix by <i>
                case 'beris', 'bor', 'bo': $word = substr($word, 0, -strlen($suffixB)).'bi'; break; // replace suffix by <bi>
                case 'ero': $word = substr($word, 0, -strlen($suffixB)).'eri'; break; // replace suffix by <eri>
                default: $word = substr($word, 0, -strlen($suffixB)); break; // remove the suffix
            }
            break; // remove only one suffix
        }
    }
    if (strlen($word) >= 2) { $verbBased = $word; } else { $verbBased = ''; } // add only if word contains two or more characters
    return array($nounBased, $verbBased);
}
?>

أسئلتي:

1) هل سيعمل هذا الرمز بشكل صحيح؟ هل تتبع قواعد الخوارزمية؟

2) كيف يمكنك تحسين الكود (الأداء)؟

شكرا جزيلا لك مقدما!

هل كانت مفيدة؟

المحلول

لا ، لن تعمل وظيفتك ، فهي تحتوي على أخطاء في بناء الجملة. على سبيل المثال ، لديك عروض أسعار غير مخصصة وتستخدم خطأً switch بناء الجملة.

هنا إعادة كتابة الوظيفة. نظرًا لأن الكاذبة في تلك الصفحة ليست دقيقة حقًا ، كان عليّ القيام ببعض التفسير. لقد فسرته بطريقة تعمل الأمثلة المذكورة في هذه المقالة.

لقد قمت أيضًا ببعض التحسينات. أول واحد هو أنني أحدد الكلمة واللاحقة المصفوفات static. وبالتالي فإن جميع المكالمات لهذه الوظيفة تشترك في نفس المصفوفات التي يجب أن تكون أداءً جيدًا ؛)

علاوة على ذلك ، قمت بتعديل المصفوفات حتى يمكن استخدامها أكثر فعالية. لقد غيرت $queWords صفيف بحيث يمكن استخدامه لإجراء بحث سريع عن طاولة التجزئة ، وليس بطيئًا in_array. علاوة على ذلك ، قمت بحفظ أطوال اللاحقات في الصفيف. وبالتالي ، لا تحتاج إلى حسابها في وقت التشغيل (وهو أمر بطيء حقًا). ربما أجريت المزيد من التحسينات البسيطة.

لا أعرف كم هو أسرع هذا الرمز ، ولكن يجب أن يكون أسرع بكثير. علاوة على ذلك ، يعمل الآن على الأمثلة المقدمة.

هنا هو الرمز:

<?php
    function stemLatin($word) {
        static $queWords = array(
            'atque'         => 1,
            'quoque'        => 1,
            'neque'         => 1,
            'itaque'        => 1,
            'absque'        => 1,
            'apsque'        => 1,
            'abusque'       => 1,
            'adaeque'       => 1,
            'adusque'       => 1,
            'denique'       => 1,
            'deque'         => 1,
            'susque'        => 1,
            'oblique'       => 1,
            'peraeque'      => 1,
            'plenisque'     => 1,
            'quandoque'     => 1,
            'quisque'       => 1,
            'quaeque'       => 1,
            'cuiusque'      => 1,
            'cuique'        => 1,
            'quemque'       => 1,
            'quamque'       => 1,
            'quaque'        => 1,
            'quique'        => 1,
            'quorumque'     => 1,
            'quarumque'     => 1,
            'quibusque'     => 1,
            'quosque'       => 1,
            'quasque'       => 1,
            'quotusquisque' => 1,
            'quousque'      => 1,
            'ubique'        => 1,
            'undique'       => 1,
            'usque'         => 1,
            'uterque'       => 1,
            'utique'        => 1,
            'utroque'       => 1,
            'utribique'     => 1,
            'torque'        => 1,
            'coque'         => 1,
            'concoque'      => 1,
            'contorque'     => 1,
            'detorque'      => 1,
            'decoque'       => 1,
            'excoque'       => 1,
            'extorque'      => 1,
            'obtorque'      => 1,
            'optorque'      => 1,
            'retorque'      => 1,
            'recoque'       => 1,
            'attorque'      => 1,
            'incoque'       => 1,
            'intorque'      => 1,
            'praetorque'    => 1,
        );
        static $suffixesNoun = array(
            'ibus' => 4,
            'ius'  => 3,
            'ae'   => 2,
            'am'   => 2,
            'as'   => 2,
            'em'   => 2,
            'es'   => 2,
            'ia'   => 2,
            'is'   => 2,
            'nt'   => 2,
            'os'   => 2,
            'ud'   => 2,
            'um'   => 2,
            'us'   => 2,
            'a'    => 1,
            'e'    => 1,
            'i'    => 1,
            'o'    => 1,
            'u'    => 1,
        );
        static $suffixesVerb = array(
            'iuntur' => 6,
            'beris'  => 5,
            'erunt'  => 5,
            'untur'  => 5,
            'iunt'   => 4,
            'mini'   => 4,
            'ntur'   => 4,
            'stis'   => 4,
            'bor'    => 3,
            'ero'    => 3,
            'mur'    => 3,
            'mus'    => 3,
            'ris'    => 3,
            'sti'    => 3,
            'tis'    => 3,
            'tur'    => 3,
            'unt'    => 3,
            'bo'     => 2,
            'ns'     => 2,
            'nt'     => 2,
            'ri'     => 2,
            'm'      => 1,
            'r'      => 1,
            's'      => 1,
            't'      => 1,
        );

        $stems = array($word, $word);

        $word = strtr(strtolower(trim($word)), 'jv', 'iu'); // trim, lowercase and j => i, v => u

        if (substr($word, -3) == 'que') {
            if (isset($queWords[$word])) {
                return array($word, $word);
            }
            $word = substr($word, 0, -3);
        }

        foreach ($suffixesNoun as $suffix => $length) {
            if (substr($word, -$length) == $suffix) {
                $tmp = substr($word, 0, -$length);

                if (isset($tmp[1]))
                    $stems[0] = $tmp;
                break;
            }
        }

        foreach ($suffixesVerb as $suffix => $length) {
            if (substr($word, -$length) == $suffix) {
                switch ($suffix) {
                    case 'iuntur':
                    case 'erunt':
                    case 'untur':
                    case 'iunt':
                    case 'unt':
                        $tmp = substr_replace($word, 'i', -$length, $length);
                    break;
                    case 'beris':
                    case 'bor':
                    case 'bo':
                        $tmp = substr_replace($word, 'bi', -$length, $length);
                    break;
                    case 'ero':
                        $tmp = substr_replace($word, 'eri', -$length, $length);
                    break;
                    default:
                        $tmp = substr($word, 0, -$length);
                }

                if (isset($tmp[1]))
                    $stems[1] = $tmp;
                break;
            }
        }

        return $stems;
    }

    var_dump(stemLatin('aquila'));
    var_dump(stemLatin('portat'));
    var_dump(stemLatin('portis'));

نصائح أخرى

بقدر ما أستطيع أن أقول ، يتبع هذا الخوارزمية الموضحة في الرابط الخاص بك ، ويجب أن تعمل بشكل صحيح. (بصرف النظر عن خطأ بناء الجملة لديك في تعريف $suffixesA - أنت تفتقد زوجين من الفواصل.)

من ناحية الأداء ، لا يبدو أن هناك الكثير مما يكسبه هنا ، ولكن هناك بعض الأشياء التي تتبادر إلى الذهن.

إذا تم استدعاء هذا عدة مرات أثناء تنفيذ واحد للنص ، فقد يكون هناك شيء اكتسبه من خلال تحديد هذه المصفوفات خارج الوظيفة - لا أعتقد أن PHP ذكي بما يكفي لتخزين هذه المصفوفات بين المكالمات إلى الوظيفة.

يمكنك أيضًا الجمع بين هذين الاثنين str_replaceفي واحد: $word = str_replace(array('j','v'), array('i','u'), $word);, ، أو نظرًا لأنك تستبدل أحرفًا واحدة بأحرف واحدة ، يمكنك استخدامها $word = strtr($word,'jv','iu'); - لكنني لا أعتقد أن هذا سيحدث فرقًا كبيرًا في الممارسة العملية. سيكون عليك تجربتها لتكون متأكدا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top