مكدس C ++ لأنواع بيانات متعددة (حاسبة متجه RPN)

StackOverflow https://stackoverflow.com/questions/2835847

  •  26-09-2019
  •  | 
  •  

سؤال

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

أقوم بتمديد هذا البرنامج ، وسأجعله يعمل كآلة حاسبة RPN ، لعمليات النوع:

1 2 3
4 5 6
x
out: -3 6 -3

(أعط متجهًا واحدًا ، متجهًا آخر ، ومشغل "Cross" ؛ يبصقون المنتج المتقاطع)

يجب أن يقبل المكدس ناقلات ثلاثية الأبعاد أو أرقام ، لعمليات مثل:

1 2 3
2
*
out: 2 4 6

يعد Lexer و Parser لهذا الكالحيا المصغرة تافهة ، لكن لا يمكنني التفكير في طريقة جيدة لإنشاء المكدس الداخلي. كيف يمكنك إنشاء كومة لاحتواء المتجهات أو الزوجي (لقد قمت بتشغيل فئة المتجهات البسيطة للغاية - أقل من مائة خط وهو يفعل كل ما أحتاجه).

كيف يمكنني إنشاء مكدس بسيط يقبل عناصر متجه الفئة أو الكتابة المزدوجة؟

شكرًا لك.

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

المحلول

أبسط طريقة هي مجرد إنشاء Operand الهيكل الذي يحتوي على ملف double من أجل العددية و Vector كائن للمتجه:

struct Operand
{
    double scalar_;
    Vector vector_;
    bool isVector_;
};

(يمكنك ضبط isVector_ صحيح إذا كان معامل متجه ، وخطأ إذا كان معاملًا قياسيًا)

للحصول على المكدس الفعلي ، يمكنك فقط الاستخدام std::stack<Operand>.

تشمل الخيارات الأخرى الميراث (إنشاء أنواع العددية والناقلات المستمدة من نوع الأساس المعامل) أو شيء من هذا القبيل boost::variant, ، ولكن لشيء بسيط مثل هذا ، بنية تكوين مثل Operand يظهر أعلاه ربما أسهل طريقة للقيام بذلك.

نصائح أخرى

هل نظرت إلى تعزيز :: أي?

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

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

#include <cstdlib>
#include <iostream>

struct Vector
{
    double x, y, z;
};

struct Element
{
    enum Type { SCALAR, VECTOR };
    Type type;
    union {
        double scalar;
        Vector v;
    } data;
};

int main(void)
{
    Element vector_element;
    vector_element.type = Element::VECTOR;
    vector_element.data.v.x = 1;
    vector_element.data.v.y = 2;
    vector_element.data.v.z = 3;

    Element scalar_element;
    scalar_element.type = Element::SCALAR;
    scalar_element.data.scalar = 3.142;

    std::cout << "The size of type Element without enum would be: " << (sizeof(Element) - sizeof(Element::Type)) << " bytes." << std::endl;

    return EXIT_SUCCESS;
}

بالمناسبة ، لسبب غريب ، ينتج عن هذا إلى 28 بايت. كنت أتوقع 3 * 8 = 24 بايت.

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