Rekursiver Abstieg
-
Hallo,
ich möchte gerne durch den rekursiven Abstieg mathemathische Rechenaufgaben lösen. Das klappt alles nur müsste ich das jetzt noch in eine Klasse packen die ich einmal fülle und dann immer wieder mit expr->getResult() aufrufen kann. Das ist daher wichtig, da sich das später auch auf Variablen etc. beziehen wird. Und expr sollte dann das Ergebnis mit dem neuen Variablenwert berechnen können.Meine Klasse habe ich mir so ähnlich vorgestellt:
#include <iostream> #include <list> typedef std::list<class Expression *> ExpressionList; enum Operation { ADD, SUB, MUL, DIV }; class Expression { public: Expression() { } virtual ~Expression() { } virtual int getResult() = 0; }; class Number : public Expression { private: int m_int; public: Number(int num) { m_int = num; } public: virtual int getResult() { return m_int; } }; class ExprType : public Expression { private: Operation m_op; ExpressionList m_exprList; public: ExprType(Operation op) { m_op = op; } virtual ~ExprType() { for (ExpressionList::iterator it = m_exprList.begin(); it != m_exprList.end(); ++it) { delete *it; } } public: void push(Expression *expr) { m_exprList.push_back(expr); } public: virtual int getResult() { int res = (m_op == ADD || m_op == SUB) ? 0 : 1; for (ExpressionList::iterator it = m_exprList.begin(); it != m_exprList.end(); ++it) { switch (m_op) { case ADD: res += (*it)->getResult(); break; case SUB: res -= (*it)->getResult(); break; case MUL: res *= (*it)->getResult(); break; case DIV: res /= (*it)->getResult(); break; } } return res; } }; int main() { std::cout << "Mul:\n"; ExprType *mul = new ExprType('*'); mul->push(new Number(10)); mul->push(new Number(20)); mul->push(new Number(30)); std::cout << mul->getResult() << "\n" << std::endl; std::cout << "Add:\n"; ExprType *add = new ExprType('+'); add->push(new Number(10)); add->push(new Number(20)); add->push(new Number(30)); std::cout << add->getResult() << "\n" << std::endl; std::cout << "Mix:\n"; std::cout << mul->getResult() << " * " << add->getResult() << " = "; ExprType *mix = new ExprType('*'); mix->push(mul); mix->push(add); std::cout << mix->getResult() << "\n" << std::endl; // // Der Speicher von mul und add wird durch mix wieder freigegeben! // delete mix; return 0; }Lassen sich meine Klassen mit dem rekursiven Abstieg verbinden so das ich damit meine Bedingung (s. Oben) erfülle oder laufe ich da in ein Problem?
Vielen dank im Voraus,
MrY
-
MrY schrieb:
Lassen sich meine Klassen mit dem rekursiven Abstieg verbinden so das ich damit meine Bedingung (s. Oben) erfülle oder laufe ich da in ein Problem?
Die Frage lässt sich ohne deine Mithilfe nicht beantworten. (
was sind die Bedingungen?)Unabhängig davon, die switch-Konstruktion sieht nicht allzu gelungen aus. Die Operationen sollten besser alles verschiedene Knoten im Google: Abstract Syntax Tree sein.
Add : Function { getResult() { evaluateArguments(); return fold(argValues, 0, plus<int>); } }; Mul : Function { getResult() { evaluateArguments(); return fold(argValues, 1, multiplies<int>); } }; Sin : Function { getResult() { checkArity(); evaluateArguments(); return sin(argValues[0]); } }; // etc.