Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cmath>
- #include <cstring>
- #include <string>
- using namespace std;
- class Expression
- { // Abstract class
- public:
- virtual Expression* diff( ) = 0;
- virtual void print() = 0;
- virtual bool isZero() = 0; // Zero Check
- virtual bool isConst() = 0; // Constant check(Number)
- virtual float constValue() = 0; // Constant value(Number)
- };
- Expression* Simplify(Expression *ex);
- class Number : public Expression
- { // Number
- private:
- float num;
- public:
- //float num;
- Number(): num(0) {}
- Number(float val): num(val) { }
- Expression* diff( )
- {
- Expression *d_num = new Number(0);
- return d_num;
- }
- void print() { cout << num ; }
- bool isZero() { return num == 0; }
- bool isConst() { return true; }
- float constValue() { return num; }
- };
- class Variable : public Expression
- { // Variable
- private:
- //char var;
- public:
- char var;
- Variable(): var('x') { }
- Variable(char ch): var(ch) { }
- Expression* diff()
- {
- Expression *d_var = new Number(1);
- return d_var;
- }
- void print() { cout << var ; }
- bool isZero() { return false; }
- bool isConst() { return false; }
- float constValue() { return 0; }
- };
- class Add : public Expression
- { // The sum of two expressions
- protected:
- //Expression *left, *right;
- public:
- Expression *left, *right;
- Add(Expression *arg1, Expression *arg2): left(arg1), right(arg2) { }
- Expression* diff( )
- {
- Expression *ld = Simplify(left->diff( ));
- Expression *rd = Simplify(right->diff( ));
- Expression *result = Simplify(new Add(Simplify(ld), Simplify(rd)));
- return result;
- }
- void print()
- {
- cout << "(";
- left->print();
- cout << "+";
- right->print();
- cout << ")";
- }
- bool isZero() { return left->isZero() && right->isZero(); }
- bool isConst() { return left->isConst() && right->isConst(); }
- float constValue() { return left->constValue() + right->constValue(); }
- };
- class Sub : public Expression
- { // The sub of two expressions
- public:
- Expression *left, *right;
- Sub(Expression *arg1, Expression *arg2): left(arg1), right(arg2) { }
- Expression* diff( )
- {
- Expression *ld = Simplify(left->diff( ));
- Expression *rd = Simplify(right->diff( ));
- Expression *result = Simplify(new Sub(Simplify(ld), Simplify(rd)));
- return result;
- }
- void print()
- {
- cout << "(";
- left->print();
- cout << "-";
- right->print();
- cout << ")";
- }
- bool isZero() { return left->isZero() && right->isZero(); }
- bool isConst() { return left->isConst() && right->isConst(); }
- float constValue() { return left->constValue() - right->constValue(); }
- };
- class Mul : public Expression
- { // Composition (ab)' = a'b + ab';
- public:
- Expression *left, *right;
- Mul(Expression *arg1, Expression *arg2): left(arg1), right(arg2) { }
- void print()
- {
- cout << "(";
- left->print();
- cout << "*";
- right->print();
- cout << ")";
- }
- Expression* diff( )
- {
- Expression *ld = Simplify(new Mul(left->diff( ), right));
- Expression *rd = Simplify(new Mul(left, right->diff( )));
- Expression *result = Simplify(new Add(ld, rd));
- return result;
- }
- bool isZero() { return left->isZero() || right->isZero(); }
- bool isConst() { return left->isConst() && right->isConst(); }
- float constValue() { return left->constValue() * right->constValue(); }
- };
- class Div : public Expression
- { // quotient (a/b)' = (a'b - ab')/b^2
- public:
- Expression *left, *right;
- Div(Expression *arg1, Expression *arg2): left(arg1), right(arg2) { }
- void print()
- {
- cout << "(";
- left->print();
- cout << "/";
- right->print();
- cout << ")";
- }
- Expression *diff( )
- {
- Expression *dl = Simplify(left->diff( ));
- Expression *dr = Simplify(right->diff( ));
- Expression *l = Simplify(new Mul(dl, right));
- Expression *r = Simplify(new Mul(left, dr));
- Expression *bottom = Simplify(new Mul(right, right));
- Expression *result = new Div(Simplify(new Sub(l, r)), bottom);
- return result;
- }
- bool isZero() { return left->isZero(); }
- bool isConst() { return left->isConst() && (right->isConst() && !right->isZero()); }
- float constValue() { return left->constValue() / right->constValue(); }
- };
- class Pow : public Expression
- { // (x^y)' = y*x^(y-1)
- public:
- Expression *arg;
- Expression *degree;
- Pow(Expression *arg1, Expression *arg2): arg(arg1), degree(arg2) { }
- void print()
- {
- cout << "(";
- arg->print();
- cout << "^";
- degree->print();
- cout << ")";
- }
- Expression *diff( )
- { //(x+6)^10 // d(osn)*1degree*2(osn)^degree-1
- Expression *dosn = Simplify(arg->diff( ));
- Expression *newdeg = Simplify(new Sub(degree, new Number(1)));
- Expression *first = new Mul(Simplify(dosn), Simplify(new Number(degree->constValue())));
- Expression *newpow = new Pow(Simplify(arg), Simplify(new Sub(degree, new Number(1))) );
- Expression *result = Simplify( new Mul(Simplify(first),Simplify(newpow)) );
- return result;
- }
- bool isZero() { return arg->isZero(); }
- bool isConst() { return arg->isConst(); }
- float constValue() { return pow(arg->constValue(), degree->constValue()); }
- };
- Expression* Simplify(Expression *ex)
- { // A function that simplifies the appearance of an expression.
- // NUMBER
- if (ex->isConst())
- { // For Number
- return new Number(ex->constValue());
- }
- // MUL
- if (typeid(*ex) == typeid(Mul))
- {
- Mul *exM = (Mul*)ex; ///Как это дерьмо работает? Спросить Марка
- Expression *exMl = Simplify(exM->left);
- Expression *exMr = Simplify(exM->right);
- if (typeid(*exMl) == typeid(Variable) && typeid(*exMr) == typeid(Variable))
- { // x*x
- Variable *v = (Variable*)exMl;
- return new Pow(new Variable(v->var), new Number(2)); // x^2
- }
- if (exMr->isConst() && exMr->constValue() == 1)
- { // x*1
- return Simplify(exMl);
- }
- if (exMl->isConst() && exMl->constValue() == 1)
- { // 1*x
- return Simplify(exMr);
- }
- if (exMr->isZero())
- { // x*0
- return new Number(0);
- }
- if (exMl->isZero())
- { // 0*x
- return new Number(0);
- }
- if (exMl->isConst())
- { // const*x
- if (typeid(*exMr) == typeid(Mul))
- { // const*(a*b)
- Expression *a = ((Mul*)exMr)->left;
- Expression *b = ((Mul*)exMr)->right;
- if (a->isConst())
- { // const*(const*b)
- return new Mul(Simplify(new Mul(exMl, a)), b);
- }
- if (b->isConst())
- { // const*(a*const)
- return new Mul(a, Simplify(new Mul(exMl, b)));
- }
- }
- }
- if (exMr->isConst())
- { // Similar to the top
- if (typeid(*exMl) == typeid(Mul))
- {
- Expression *a = ((Mul*)exMl)->left;
- Expression *b = ((Mul*)exMl)->right;
- if (a->isConst())
- {
- return new Mul(Simplify(new Mul(exMr, a)), b);
- }
- if (b->isConst())
- {
- return new Mul(a, Simplify(new Mul(exMr, b)));
- }
- }
- }
- // x*(1/y) = (x/y) = (1/y)*x
- /*if (typeid(exMr) == typeid(Div))
- { // x*(a1/b1)
- Expression *a1 = ((Div*)exMr)->left;
- Expression *b1 = ((Div*)exMr)->right;
- if (a1->isConst && a1->constValue == 1)
- {
- return new Div( Simplify(exMl), Simplify(b1) );
- }
- }*/
- }
- // ADD
- if (typeid(*ex) == typeid(Add))
- { //
- Add *exA = (Add*)ex;
- Expression *a1 = Simplify(exA->left); // a1 + b1
- Expression *b1 = Simplify(exA->right);
- if (typeid(*a1) == typeid(Variable) && typeid(*b1) == typeid(Variable))
- { // x+x
- Variable *v = (Variable*)a1;
- return new Mul(new Number(2), new Variable(v->var));
- }
- if (a1->isZero())
- { // 0+b1
- return Simplify(b1);
- }
- if (b1->isZero())
- { // a1+0
- return Simplify(a1);
- }
- }
- // DIV
- if (typeid(*ex) == typeid(Div))
- {
- Div *exD = (Div*)ex;
- Expression *exDl = Simplify(exD->left);
- Expression *exDr = Simplify(exD->right);
- if (exDr->isConst() && exDr->constValue() == 1)
- { // x/1
- return Simplify(exDl);
- }
- if (exDl->isZero())
- { // 0/x
- return new Number(0);
- }
- }
- // POW
- if (typeid(*ex) == typeid(Pow))
- {
- Pow *exP = (Pow*)ex;
- Expression *exPl = Simplify(exP->arg);
- Expression *exPr = Simplify(exP->degree);
- if (exPr->isZero())
- { // x^0
- return new Number(1);
- }
- if (exPr->isConst() && exPr->constValue() == 1)
- { // x^1
- return Simplify(exPl);
- }
- if (exPr->isConst())
- { // If the degree is a numeric expression
- return new Pow(Simplify(exPl), new Number(exPr->constValue()));
- }
- }
- // SUB
- if (typeid(*ex) == typeid(Sub))
- {
- Sub *exS = (Sub*)ex;
- Expression *exSl = Simplify(exS->left);
- Expression *exSr = Simplify(exS->right);
- if (exSl->isZero())
- { // 0-x = -x
- Expression *result = Simplify( new Mul( new Number(-1), Simplify(exSr) ) );
- return result;
- }
- if (exSr->isZero())
- { // x-0
- return Simplify(exSl);
- }
- }
- return ex;
- }
- int main()
- {
- // Number
- Expression *n = new Number(123);
- n->print();
- Expression *dn = n->diff( );
- cout << "' = ";
- dn->print();
- cout << endl;
- // Variable
- Expression *x = new Variable('x');
- x->print();
- Expression *dx = x->diff( );
- cout << "' = ";
- dx->print();
- cout << endl;
- // Add
- Expression *sum = new Add(new Variable('x'), new Variable('x'));
- sum->print();
- Expression *dsum = sum->diff( );
- cout << "' = ";
- dsum->print();
- cout << endl;
- // Sub
- Expression *dif = new Sub(new Variable('x'), new Number(2));
- dif->print();
- Expression *ddif = dif->diff( );
- cout << "' = ";
- ddif->print();
- cout << endl;
- // Mul
- Expression *mul = new Mul(new Variable('x'), new Div( new Number(1),new Variable('x')) );
- mul->print();
- Expression *dmul = mul->diff( );
- cout << "' = ";
- dmul->print();
- cout << endl;
- // Div
- Expression *div = new Div(new Variable('y'), new Variable('x'));
- div->print();
- Expression *ddiv = div->diff( );
- cout << "' = ";
- ddiv->print();
- cout << endl;
- // Pow
- Expression *pow = new Pow(new Variable('x'), new Variable('b'));
- pow->print();
- Expression *dpow = pow->diff( );
- cout << "' = ";
- dpow->print();
- cout << endl;
- //char *str = "123456789";
- //cout << SubString(str,3,7);
- // (x+y)^(1/3)
- //Expression* e = new Log(3, new Add(new Number(1), new Variable('x')));
- Expression *e = new Mul( new Add(new Mul(new Number(15), new Variable('x')), new Variable('x')), new Sub(new Variable('x'),new Number(1)));
- Expression* de = e->diff();
- e->print();
- cout << "\n";
- de->print();
- cout << "\n";
- delete e;
- delete de;
- system("pause");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement