Advertisement
vadimk772336

Untitled

Nov 18th, 2019
249
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.25 KB | None | 0 0
  1. #include <iostream>
  2. #include <cmath>
  3. #include <cstring>
  4. #include <string>
  5.  
  6. using namespace std;
  7.  
  8. class Expression
  9. { // Abstract class
  10. public:
  11.     virtual Expression* diff( ) = 0;
  12.     virtual void print() = 0;
  13.     virtual bool isZero() = 0; // Zero Check
  14.     virtual bool isConst() = 0; // Constant check(Number)
  15.     virtual float constValue() = 0; // Constant value(Number)
  16. };
  17.  
  18. Expression* Simplify(Expression *ex);
  19.  
  20. class Number : public Expression
  21. { // Number
  22. private:
  23.     float num;
  24. public:
  25.     //float num;
  26.     Number(): num(0) {}
  27.     Number(float val): num(val) { }
  28.     Expression* diff( )
  29.     {
  30.         Expression *d_num = new Number(0);
  31.         return d_num;
  32.     }
  33.     void print() { cout << num ; }
  34.     bool isZero() { return num == 0; }
  35.     bool isConst() { return true; }
  36.     float constValue() { return num; }
  37. };
  38.  
  39. class Variable : public Expression
  40. { // Variable
  41. private:
  42.     //char var;
  43. public:
  44.     char var;
  45.     Variable(): var('x') { }
  46.     Variable(char ch): var(ch) { }
  47.     Expression* diff()
  48.     {
  49.        
  50.        
  51.             Expression *d_var = new Number(1);
  52.             return d_var;
  53.        
  54.     }
  55.     void print() { cout << var ; }
  56.     bool isZero() { return false; }
  57.     bool isConst() { return false; }
  58.     float constValue() { return 0; }
  59. };
  60.  
  61. class Add : public Expression
  62. { // The sum of two expressions
  63. protected:
  64.     //Expression *left, *right;
  65. public:
  66.     Expression *left, *right;
  67.     Add(Expression *arg1, Expression *arg2): left(arg1), right(arg2) { }
  68.     Expression* diff( )
  69.     {
  70.         Expression *ld = Simplify(left->diff( ));
  71.         Expression *rd = Simplify(right->diff( ));
  72.         Expression *result = Simplify(new Add(Simplify(ld), Simplify(rd)));
  73.         return result;
  74.     }
  75.     void print()
  76.     {
  77.         cout << "(";
  78.         left->print();
  79.         cout << "+";
  80.         right->print();
  81.         cout << ")";
  82.     }
  83.     bool isZero() { return left->isZero() && right->isZero(); }
  84.     bool isConst() { return left->isConst() && right->isConst(); }
  85.     float constValue() { return left->constValue() + right->constValue(); }
  86. };
  87.  
  88. class Sub : public Expression
  89. { // The sub of two expressions
  90. public:
  91.     Expression *left, *right;
  92.     Sub(Expression *arg1, Expression *arg2): left(arg1), right(arg2) { }
  93.     Expression* diff( )
  94.     {
  95.         Expression *ld = Simplify(left->diff( ));
  96.         Expression *rd = Simplify(right->diff( ));
  97.         Expression *result = Simplify(new Sub(Simplify(ld), Simplify(rd)));
  98.         return result;
  99.     }
  100.     void print()
  101.     {
  102.         cout << "(";
  103.         left->print();
  104.         cout << "-";
  105.         right->print();
  106.         cout << ")";
  107.     }
  108.     bool isZero() { return left->isZero() && right->isZero(); }
  109.     bool isConst() { return left->isConst() && right->isConst(); }
  110.     float constValue() { return left->constValue() - right->constValue(); }
  111. };
  112.  
  113. class Mul : public Expression
  114. { // Composition (ab)' = a'b + ab';
  115. public:
  116.     Expression *left, *right;
  117.     Mul(Expression *arg1, Expression *arg2): left(arg1), right(arg2) { }
  118.     void print()
  119.     {
  120.         cout << "(";
  121.         left->print();
  122.         cout << "*";
  123.         right->print();
  124.         cout << ")";
  125.     }
  126.     Expression* diff( )
  127.     {
  128.         Expression *ld = Simplify(new Mul(left->diff( ), right));
  129.         Expression *rd = Simplify(new Mul(left, right->diff( )));
  130.         Expression *result = Simplify(new Add(ld, rd));
  131.         return result;
  132.     }
  133.     bool isZero() { return left->isZero() || right->isZero(); }
  134.     bool isConst() { return left->isConst() && right->isConst(); }
  135.     float constValue() { return left->constValue() * right->constValue(); }
  136. };
  137.  
  138. class Div : public Expression
  139. { // quotient (a/b)' = (a'b - ab')/b^2
  140. public:
  141.     Expression *left, *right;
  142.     Div(Expression *arg1, Expression *arg2): left(arg1), right(arg2) { }
  143.     void print()
  144.     {
  145.         cout << "(";
  146.         left->print();
  147.         cout << "/";
  148.         right->print();
  149.         cout << ")";
  150.     }
  151.     Expression *diff( )
  152.     {
  153.         Expression *dl = Simplify(left->diff( ));
  154.         Expression *dr = Simplify(right->diff( ));
  155.         Expression *l = Simplify(new Mul(dl, right));
  156.         Expression *r = Simplify(new Mul(left, dr));
  157.         Expression *bottom = Simplify(new Mul(right, right));
  158.         Expression *result = new Div(Simplify(new Sub(l, r)), bottom);
  159.         return result;
  160.     }
  161.     bool isZero() { return left->isZero(); }
  162.     bool isConst() { return left->isConst() && (right->isConst() && !right->isZero()); }
  163.     float constValue() { return left->constValue() / right->constValue(); }
  164. };
  165.  
  166. class Pow : public Expression
  167. { //  (x^y)' = y*x^(y-1)
  168. public:
  169.     Expression *arg;
  170.     Expression *degree;
  171.     Pow(Expression *arg1, Expression *arg2): arg(arg1), degree(arg2) { }
  172.     void print()
  173.     {
  174.         cout << "(";
  175.         arg->print();
  176.         cout << "^";
  177.         degree->print();
  178.         cout << ")";
  179.     }
  180.     Expression *diff( )
  181.     { //(x+6)^10 // d(osn)*1degree*2(osn)^degree-1
  182.         Expression *dosn = Simplify(arg->diff( ));
  183.         Expression *newdeg = Simplify(new Sub(degree, new Number(1)));
  184.         Expression *first = new Mul(Simplify(dosn), Simplify(new Number(degree->constValue())));
  185.         Expression *newpow = new Pow(Simplify(arg), Simplify(new Sub(degree, new Number(1))) );
  186.         Expression *result = Simplify( new Mul(Simplify(first),Simplify(newpow)) );
  187.         return result;
  188.     }
  189.     bool isZero() { return arg->isZero(); }
  190.     bool isConst() { return arg->isConst(); }
  191.     float constValue() { return pow(arg->constValue(), degree->constValue()); }
  192. };
  193.  
  194.  
  195. Expression* Simplify(Expression *ex)
  196. { // A function that simplifies the appearance of an expression.
  197.     // NUMBER
  198.     if (ex->isConst())
  199.     { // For Number
  200.         return new Number(ex->constValue());
  201.     }
  202.     // MUL
  203.     if (typeid(*ex) == typeid(Mul))
  204.     {
  205.         Mul *exM = (Mul*)ex;          ///Как это дерьмо работает? Спросить Марка
  206.         Expression *exMl = Simplify(exM->left);
  207.         Expression *exMr = Simplify(exM->right);
  208.         if (typeid(*exMl) == typeid(Variable) && typeid(*exMr) == typeid(Variable))
  209.         { // x*x
  210.             Variable *v = (Variable*)exMl;
  211.             return new Pow(new Variable(v->var), new Number(2)); // x^2
  212.         }
  213.         if (exMr->isConst() && exMr->constValue() == 1)
  214.         { // x*1
  215.             return Simplify(exMl);
  216.         }
  217.         if (exMl->isConst() && exMl->constValue() == 1)
  218.         { // 1*x
  219.             return Simplify(exMr);
  220.         }
  221.         if (exMr->isZero())
  222.         { // x*0
  223.             return new Number(0);
  224.         }
  225.         if (exMl->isZero())
  226.         { // 0*x
  227.             return new Number(0);
  228.         }
  229.         if (exMl->isConst())
  230.         { // const*x
  231.             if (typeid(*exMr) == typeid(Mul))
  232.             { // const*(a*b)
  233.                 Expression *a = ((Mul*)exMr)->left;
  234.                 Expression *b = ((Mul*)exMr)->right;
  235.                 if (a->isConst())
  236.                 { // const*(const*b)
  237.                     return new Mul(Simplify(new Mul(exMl, a)), b);
  238.                 }
  239.                 if (b->isConst())
  240.                 { // const*(a*const)
  241.                     return new Mul(a, Simplify(new Mul(exMl, b)));
  242.                 }
  243.             }
  244.         }
  245.         if (exMr->isConst())
  246.         { // Similar to the top
  247.             if (typeid(*exMl) == typeid(Mul))
  248.             {
  249.                 Expression *a = ((Mul*)exMl)->left;
  250.                 Expression *b = ((Mul*)exMl)->right;
  251.                 if (a->isConst())
  252.                 {
  253.                     return new Mul(Simplify(new Mul(exMr, a)), b);
  254.                 }
  255.                 if (b->isConst())
  256.                 {
  257.                     return new Mul(a, Simplify(new Mul(exMr, b)));
  258.                 }
  259.             }
  260.         }
  261.         // x*(1/y) = (x/y) = (1/y)*x
  262.         /*if (typeid(exMr) == typeid(Div))
  263.         { // x*(a1/b1)
  264.             Expression *a1 = ((Div*)exMr)->left;
  265.             Expression *b1 = ((Div*)exMr)->right;
  266.             if (a1->isConst && a1->constValue == 1)
  267.             {
  268.                 return new Div( Simplify(exMl), Simplify(b1) );
  269.             }
  270.         }*/
  271.     }
  272.     // ADD
  273.     if (typeid(*ex) == typeid(Add))
  274.     { //
  275.         Add *exA = (Add*)ex;
  276.         Expression *a1 = Simplify(exA->left); // a1 + b1
  277.         Expression *b1 = Simplify(exA->right);
  278.         if (typeid(*a1) == typeid(Variable) && typeid(*b1) == typeid(Variable))
  279.         { // x+x
  280.             Variable *v = (Variable*)a1;
  281.             return new Mul(new Number(2), new Variable(v->var));
  282.         }
  283.         if (a1->isZero())
  284.         { // 0+b1
  285.             return Simplify(b1);
  286.         }
  287.         if (b1->isZero())
  288.         { // a1+0
  289.             return Simplify(a1);
  290.         }
  291.     }
  292.     // DIV
  293.     if (typeid(*ex) == typeid(Div))
  294.     {
  295.         Div *exD = (Div*)ex;
  296.         Expression *exDl = Simplify(exD->left);
  297.         Expression *exDr = Simplify(exD->right);
  298.         if (exDr->isConst() && exDr->constValue() == 1)
  299.         { // x/1
  300.             return Simplify(exDl);
  301.         }
  302.         if (exDl->isZero())
  303.         { // 0/x
  304.             return new Number(0);
  305.         }
  306.     }
  307.     // POW
  308.     if (typeid(*ex) == typeid(Pow))
  309.     {
  310.         Pow *exP = (Pow*)ex;
  311.         Expression *exPl = Simplify(exP->arg);
  312.         Expression *exPr = Simplify(exP->degree);
  313.         if (exPr->isZero())
  314.         { // x^0
  315.             return new Number(1);
  316.         }
  317.         if (exPr->isConst() && exPr->constValue() == 1)
  318.         { // x^1
  319.             return Simplify(exPl);
  320.         }
  321.         if (exPr->isConst())
  322.         { // If the degree is a numeric expression
  323.             return new Pow(Simplify(exPl), new Number(exPr->constValue()));
  324.         }
  325.     }
  326.     // SUB
  327.     if (typeid(*ex) == typeid(Sub))
  328.     {
  329.         Sub *exS = (Sub*)ex;
  330.         Expression *exSl = Simplify(exS->left);
  331.         Expression *exSr = Simplify(exS->right);
  332.         if (exSl->isZero())
  333.         { // 0-x = -x
  334.             Expression *result = Simplify( new Mul( new Number(-1), Simplify(exSr) ) );
  335.             return result;
  336.         }
  337.         if (exSr->isZero())
  338.         { // x-0
  339.             return Simplify(exSl);
  340.         }
  341.     }
  342.     return ex;
  343. }
  344.  
  345.  
  346.  
  347.  
  348.  
  349. int main()
  350. {
  351.     // Number
  352.     Expression *n = new Number(123);
  353.     n->print();
  354.     Expression *dn = n->diff( );
  355.     cout << "' = ";
  356.     dn->print();
  357.     cout << endl;
  358.     // Variable
  359.     Expression *x = new Variable('x');
  360.     x->print();
  361.     Expression *dx = x->diff( );
  362.     cout << "' = ";
  363.     dx->print();
  364.     cout << endl;
  365.    
  366.     // Add
  367.     Expression *sum = new Add(new Variable('x'), new Variable('x'));
  368.     sum->print();
  369.     Expression *dsum = sum->diff( );
  370.     cout << "' = ";
  371.     dsum->print();
  372.     cout << endl;
  373.     // Sub
  374.     Expression *dif = new Sub(new Variable('x'), new Number(2));
  375.     dif->print();
  376.     Expression *ddif = dif->diff( );
  377.     cout << "' = ";
  378.     ddif->print();
  379.     cout << endl;
  380.     // Mul
  381.     Expression *mul = new Mul(new Variable('x'), new Div( new Number(1),new Variable('x')) );
  382.     mul->print();
  383.     Expression *dmul = mul->diff( );
  384.     cout << "' = ";
  385.     dmul->print();
  386.     cout << endl;
  387.     // Div
  388.     Expression *div = new Div(new Variable('y'), new Variable('x'));
  389.     div->print();
  390.     Expression *ddiv = div->diff( );
  391.     cout << "' = ";
  392.     ddiv->print();
  393.     cout << endl;
  394.     // Pow
  395.     Expression *pow = new Pow(new Variable('x'), new Variable('b'));
  396.     pow->print();
  397.     Expression *dpow = pow->diff( );
  398.     cout << "' = ";
  399.     dpow->print();
  400.     cout << endl;
  401.    
  402.     //char *str = "123456789";
  403.     //cout << SubString(str,3,7);
  404.     // (x+y)^(1/3)
  405.  
  406.     //Expression* e = new Log(3, new Add(new Number(1), new Variable('x')));
  407.     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)));
  408.     Expression* de = e->diff();
  409.     e->print();
  410.     cout << "\n";
  411.     de->print();
  412.     cout << "\n";
  413.     delete e;
  414.     delete de;
  415.     system("pause");
  416.     return 0;
  417. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement