المحاضرة 10: تقييم التعبيرات باستخدام المكدس

جامعة حمص - كلية الهندسة المعلوماتية - السنة الثانية

المحاضر

ناديا خرسان

المادة

الخوارزميات وبنى المعطيات 1

النوع

تقييم التعبيرات باستخدام المكدس

تقييم التعبير الملحق (Postfix)

تستخدم المكدسات في تقييم التعبيرات المكتوبة بالنمط الملحق (Postfix) حيث تكون العملية بعد المعاملات

الخوارزمية:

1 مرر على كل محرف في التعبير
2 إذا كان المحرف رقماً: أضفه إلى المكدس
3 إذا كان المحرف عملية حسابية:
4 أخرج الرقمين العلويين من المكدس (op2 ثم op1)
5 طبق العملية الحسابية على الرقمين (op1 عملية op2)
6 أدخل النتيجة في المكدس
7 بعد الانتهاء: القيمة في المكدس هي النتيجة

مثال: تقييم التعبير "89 8 - 3 + / 6 1 - * 2 *"

النتيجة: 20

الخطوات:

  1. 9 و 8: عملية طرح → 1
  2. 1 و 3: عملية جمع → 4
  3. 8 و 4: عملية قسمة → 2
  4. 6 و 1: عملية طرح → 5
  5. 2 و 5: عملية ضرب → 10
  6. 10 و 2: عملية ضرب → 20
// تقييم التعبير الملحق (Postfix)
#include <iostream>
#include "stack.h"
#include <cctype>

float evalPostfix(char exp[]) {
    Stack<float> s;
    float op1, op2;

    for (int i = 0; exp[i] != '\0'; ++i) {
        if (isdigit(exp[            s.push(exp[i] - '0');
        } else {
            op1 = s.pop();
            op2 = s.pop();
            switch (exp[i]) {
                case '+': s.push(op2 + op1); break;
                case '-': s.push(op2 - op1); break;
                case '*': s.push(op2 * op1); break;
                case '/': s.push(op2 / op1); break;
            }
        }
    }

    return s.pop();
}

int main() {
    char exp[100];
    std::cout << "أدخل تعبيراً ملحقاً (Postfix): ";
    std::cin >> exp;

    std::cout << "النتيجة: " << evalPostfix(exp);
    return 0;
}

محول تفاعلي: تقييم تعبير ملحق

النتيجة ستظهر هنا...

تقييم التعبير المصدر (Prefix)

تستخدم المكدسات في تقييم التعبيرات المكتوبة بالنمط المصدر (Prefix) حيث تكون العملية قبل المعاملات

الخوارزمية:

1 مرر على كل محرف في التعبير من اليمين لليسار
2 إذا كان المحرف رقماً: أضفه إلى المكدس
3 إذا كان المحرف عملية حسابية:
4 أخرج الرقمين العلويين من المكدس (op1 ثم op2)
5 طبق العملية الحسابية على الرقمين (op1 عملية op2)
6 أدخل النتيجة في المكدس
7 بعد الانتهاء: القيمة في المكدس هي النتيجة

مثال: تقييم التعبير "* / 8 + - 9 8 3 - 6 1 2"

النتيجة: 20

الخطوات (من اليمين لليسار):

  1. 6 و 1: عملية طرح → 5
  2. 9 و 8: عملية طرح → 1
  3. 1 و 3: عملية جمع → 4
  4. 8 و 4: عملية قسمة → 2
  5. 2 و 5: عملية ضرب → 10
  6. 10 و 2: عملية ضرب → 20
// تقييم التعبير المصدر (Prefix)
#include <iostream>
#include <cstring>
#include "stack.h"

float evalPrefix(char exp[]) {
    Stack<float> s;
    float op1, op2;

    for (int i = strlen(exp) - 1; i >= 0; --i) {
        if (isdigit(exp[i])) {
            s.push(exp[i] - '0');
        } else {
            op1 = s.pop();
            op2 = s.pop();
            switch (exp[i]) {
                case '+': s.push(op1 + op2); break;
                case '-': s.push(op1 - op2); break;
                case '*': s.push(op1 * op2); break;
                case '/': s.push(op1 / op2); break;
            }
        }
    }

    return s.pop();
}

int main() {
    char exp[100];
    std::cout << "أدخل تعبيراً مصدراً (Prefix): ";
    std::cin >> exp;

    std::cout << "النتيجة: " << evalPrefix(exp);
    return 0;
}

محول تفاعلي: تقييم تعبير مصدر

النتيجة ستظهر هنا...

تقييم التعبير النظامي (Infix)

تستخدم المكدسات في تقييم التعبيرات المكتوبة بالنمط النظامي (Infix) حيث تكون العملية بين المعاملات

الخوارزمية:

1 استخدم مكدسين: واحد للأرقام وآخر للعمليات والأقواس
2 مرر على كل محرف في التعبير
3 إذا كان المحرف رقماً: أضفه إلى مكدس الأرقام
4 إذا كان المحرف '(': أضفه إلى مكدس العمليات
5 إذا كان المحرف عملية حسابية:
6 أخرج العمليات ذات الأولوية الأعلى أو المتساوية من المكدس وطبقها
7 أضف العملية الحالية إلى مكدس العمليات
8 إذا كان المحرف ')': طبق جميع العمليات حتى '('
9 بعد الانتهاء: طبق العمليات المتبقية
10 القيمة في مكدس الأرقام هي النتيجة

مثال: تقييم التعبير "5+(6*3-4/2)/2+1"

النتيجة: 14

الخطوات الرئيسية:

  1. 6 * 3 = 18
  2. 4 / 2 = 2
  3. 18 - 2 = 16
  4. 16 / 2 = 8
  5. 5 + 8 = 13
  6. 13 + 1 = 14
// تقييم التعبير النظامي (Infix)
#include <iostream>
#include "stack.h"

float calculate(float num1, float num2, char op) {
    switch (op) {
        case '*': return num1 * num2;
        case '/': return num1 / num2;
        case '+': return num1 + num2;
        case '-': return num1 - num2;
    }
    return 0;
}

float evalInfix(char exp[]) {
    Stack<float> sF; // مكدس للأرقام
    Stack<char> sC; // مكدس للعمليات
    float op1, op2;
    char calc;

    for (int i = 0; exp[i] != '\0'; ++i) {
        if (isdigit(exp[i])) {
            sF.push(exp[i] - '0');
        } else if (exp[i] == '(') {
            sC.push('(');
        } else if (exp[i] == ')') {
            while (!sC.isEmpty() && sC.getTop() != '(') {
                calc = sC.pop();
                op1 = sF.pop();
                op2 = sF.pop();
                sF.push(calculate(op2, op1, calc));
            }
            if (!sC.isEmpty()) sC.pop(); // إزالة '('
        } else {
            // معالجة العمليات الحسابية
            // ... (الكود الكامل في المحاضرة)
        }
    }

    // تطبيق العمليات المتبقية
    while (!sC.isEmpty()) {
        calc = sC.pop();
        op1 = sF.pop();
        op2 = sF.pop();
        sF.push(calculate(op2, op1, calc));
    }

    return sF.pop();
}

int main() {
    char exp[100];
    std::cout << "أدخل تعبيراً نظامياً (Infix): ";
    std::cin.getline(exp, 100);

    std::cout << "النتيجة: " << evalInfix(exp);
    return 0;
}

محول تفاعلي: تقييم تعبير نظامي

النتيجة ستظهر هنا...