سؤال

أنا خلق كاس (نظام الجبر الكمبيوتر) في فب ، ولكن أنا عالقة الآن.أنا أستخدم هذا الموقع.

الآن كتبت توكينيزر.فإنه سيتم تحويل معادلة مثل هذا:

1+2x-3*(4-5*(3x))

إلى هذا:

NUMBER PLUS_OPERATOR NUMBER VAR[X] MINUS_OPERATOR NUMBER MULTIPLY_OPERATOR GROUP

(حيث المجموعة هي مجموعة أخرى من الرموز).كيف يمكنني تبسيط هذه المعادلة?نعم ، أنا أعرف ما يمكنك القيام به:إضافة س فارسولكنهم في المجموعة الفرعية.ما هي أفضل طريقة يمكنني استخدامها للتعامل مع تلك الرموز?

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

المحلول

ستكون الخطوة التالية المفيدة حقا هي إنشاء شجرة تحليل:

enter image description here

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

expression: additive

additive: multiplicative ([+-] multiplicative)*

multiplicative: primary ('*' primary)*

primary: variable
       | number
       | '(' expression ')'

لاحظ أن هذه القواعد لا تتعامل مع 2x بناء الجملة ، ولكن يجب أن يكون من السهل إضافته.

لاحظ استخدام ذكي من العودية في القواعد النحوية. primary يلتقط فقط المتغيرات والأرقام والتعبيرات بين قوسين ، ويتوقف عند تشغيله في عامل تشغيل. multiplicative يوزع واحد أو أكثر primary تعبيرات محددة بواسطة * علامات ، ولكن يتوقف عند تشغيله في + أو - التوقيع. additive يوزع واحد أو أكثر multiplicative تعبيرات محددة بواسطة + و -, ، لكنه يتوقف عندما يصطدم بـ ).ومن ثم ، فإن مخطط العودية يحدد أسبقية المشغل.

ليس من الصعب جدا بشكل رهيب لتنفيذ محلل تنبؤي باليد ، كما فعلت أدناه (انظر المثال الكامل في ideone.com):

function parse()
{
    global $tokens;
    reset($tokens);
    $ret = parseExpression();
    if (current($tokens) !== FALSE)
        die("Stray token at end of expression\n");
    return $ret;
}

function popToken()
{
    global $tokens;
    $ret = current($tokens);
    if ($ret !== FALSE)
        next($tokens);
    return $ret;
}

function parseExpression()
{
    return parseAdditive();
}

function parseAdditive()
{
    global $tokens;

    $expr = parseMultiplicative();

    for (;;) {
        $next = current($tokens);
        if ($next !== FALSE && $next->type == "operator" &&
            ($next->op == "+" || $next->op == "-"))
        {
            next($tokens);
            $left = $expr;
            $right = parseMultiplicative();
            $expr = mkOperatorExpr($next->op, $left, $right);
        } else {
            return $expr;
        }
    }
}

function parseMultiplicative()
{
    global $tokens;

    $expr = parsePrimary();

    for (;;) {
        $next = current($tokens);
        if ($next !== FALSE && $next->type == "operator" &&
            $next->op == "*")
        {
            next($tokens);
            $left = $expr;
            $right = parsePrimary();
            $expr = mkOperatorExpr($next->op, $left, $right);
        } else {
            return $expr;
        }
    }
}

function parsePrimary()
{
    $tok = popToken();
    if ($tok === FALSE)
        die("Unexpected end of token list\n");
    if ($tok->type == "variable")
        return mkVariableExpr($tok->name);
    if ($tok->type == "number")
        return mkNumberExpr($tok->value);
    if ($tok->type == "operator" && $tok->op == "(") {
        $ret = parseExpression();
        $tok = popToken();
        if ($tok->type == "operator" && $tok->op == ")")
            return $ret;
        else
            die("Missing end parenthesis\n");
    }

    die("Unexpected $tok->type token\n");
}

حسنا ، حتى الآن لديك هذه الشجرة تحليل جميلة ، وحتى صورة جميلة للذهاب معها.الآن ماذا?قد يكون هدفك (في الوقت الحالي) هو دمج المصطلحات ببساطة للحصول على نتيجة النموذج:

n1*a + n2*b + n3*c + n4*d + ...

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

نصائح أخرى

لغة PHP جيدة في السلاسل والأرقام والمصفوفات. لكنها لغة رديئة لتنفيذ التلاعب الرمزي بالصيغة ، لأنها لا تحتوي على آلية أصلية لمعالجة "التعبيرات الرمزية" ، التي تريد الأشجار لها حقًا. نعم ، يمكنك تنفيذ كل تلك الآلات. الأصعب هو إجراء المعالجات الجبرية . إنه عمل كثير جدًا إذا كنت تريد بناء شيء شبه معقد. من الناحية المثالية ، تريد أن تساعدك الآلات في كتابة التحولات بشكل مباشر وسهل.

على سبيل المثال ، كيف ستنفذ قواعد الجبر التعسفية؟ الترابطية والتبادلية؟ المصطلح "مطابقة على مسافة"؟ ، على سبيل المثال Genacodicetagpre

يمكنك إلقاء نظرة على كيفية CAS بسيطة يمكن تنفيذها باستخدام < a href="http://www.semanticdesigns.com/Products/DMS/ProgramTransformation.html" rel="nofollow"> نظام تحويل برنامج DMS . يحتوي DMS على بنيات رياضية صعبة مثل التبادلية والترابطية ، ويمكنك كتابة قواعد الجبر بشكل صريح للعمل على الصيغ الرمزية.

الكتاب الجبر الحاسوبي والحساب الرمزي: طرق رياضية بقلم جويل إس كوهين يصف خوارزمية للتبسيط التلقائي للتعبيرات الجبرية.

تُستخدم هذه الخوارزمية في مكتبة الجبر الحاسوبية Symbolism لـ C #.الذهاب مع المثال الخاص بك ، برنامج C # التالي: Genacodicetagpre يعرض

ما يلي في وحدة التحكم: Genacodicetagpre

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